-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tracker.py
97 lines (78 loc) · 3.35 KB
/
tracker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import cv2
from vidgear.gears import CamGear
import clr
import pyvirtualcam
# import c# dll
clr.AddReference(r'./PTZDevice')
from PTZ import PTZDevice, PTZType
device = PTZDevice.GetDevice("BCC950 ConferenceCam", PTZType.Relative)
net = cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")
# cv2 is slow as hell without these (and still slow with them)
cv2.setUseOptimized(True)
cv2.setNumThreads(8)
if cv2.cuda.getCudaEnabledDeviceCount() > 0:
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
# todo: add config
screen_width = 1920
screen_height = 1080
video_capture = CamGear(source=0, backend=cv2.CAP_DSHOW, **{
"CAP_PROP_FRAME_WIDTH": screen_width,
"CAP_PROP_FRAME_HEIGHT": screen_height,
"CAP_PROP_FPS": 30,
"CAP_PROP_FOURCC": cv2.VideoWriter_fourcc(*"MJPG"),
}).start()
with pyvirtualcam.Camera(width=screen_width, height=screen_height, fps=30, fmt=pyvirtualcam.PixelFormat.BGR) as cam:
while True:
frame = video_capture.read()
# prep frame for dnn
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300), [104, 117, 123], False, False)
net.setInput(blob)
detections = net.forward()
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
# we are reasonably confident this is a face
if confidence > 0.7:
box = detections[0, 0, i, 3:7] * [frame.shape[1], frame.shape[0], frame.shape[1], frame.shape[0]]
(x, y, x2, y2) = box.astype(int)
#cv2.rectangle(frame, (x, y), (x2, y2), (0, 255, 0), 2)
# we track and limit the movement to prevent the motor from clicking and making sad noises
current_y = 0
current_x = 0
# get coords of box center and see how off we are
x_center = (x + x2) / 2
x_off_center = x_center - (screen_width / 2)
y_center = (y + y2) / 2
y_off_center = y_center - (screen_height / 2)
# move camera if we are off center
if x_off_center > 100:
if current_x != 20:
current_x += 1
device.Move(1, 0)
elif x_off_center < -100:
if current_x != -20:
current_x -= 1
device.Move(-1, 0)
if y_off_center < -80:
if current_y != 5:
current_y += 1
device.Move(0, 1)
elif y_off_center > 80:
if current_y != -5:
current_y -= 1
device.Move(0, -1)
# this is copilot junk maths it really needs replacing and sorting out
square_size = (x2 - x) * (y2 - y)
screen_size = screen_width * screen_height
zoom_ratio = square_size / screen_size
zoom_off_center = zoom_ratio - (1/3)
if zoom_off_center > 0.1:
device.Zoom(1)
elif zoom_off_center < -0.1:
device.Zoom(-1)
# show frame
cam.send(frame)
# cleanup and release camera to other processes
video_capture.stop()
cv2.destroyAllWindows()