Skip to content

Instantly share code, notes, and snippets.

@RamiAwar
Created October 17, 2020 13:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RamiAwar/ba4b55b1488523315c6ca6974051fcab to your computer and use it in GitHub Desktop.
Save RamiAwar/ba4b55b1488523315c6ca6974051fcab to your computer and use it in GitHub Desktop.
'''This python code performs face tracking and simulates scrolling. First, the image feed is recieved from the camera. A facial detection algorithm is applied
once in every 5 frames. On detecting the face, a rectangular frame is drawn around the detected face, and the deviation from the center of the screen to the center of the face is taken as the scroll delta.
Requires Python + OpenCV'''
import cv2
from pynput.mouse import Button, Controller
mouse = Controller()
HAAR_CASCADE_PATH = "haarcascade_frontalface_alt.xml"
CAMERA_INDEX = 0
def detect_faces(image):
# print('detect fn' #)
faces = []
# detected = cv.HaarDetectObjects(image, cascade, storage, 1.2, 2,
# cv.CV_HAAR_DO_CANNY_PRUNING, (100,100))
detected = cascade.detectMultiScale(
image, 1.3, 4, cv2.CASCADE_SCALE_IMAGE, (20, 20))
# print(detected)
if detected != []:
# print('face detected' #)
for (x, y, w, h) in detected: # for (x,y,w,h),n in detected:
faces.append((x, y, w, h))
return faces
def get_motion(face):
# yaw is x-axis - horizontal axis
# pitch is y-axis - depth axis
# roll is z-axis - vertical axis
#[0][0] - x, [0][1] - y, [0][2] - w, [0][3] - h
threshold = 40
# w,h are approx constant for U,D,L,R events
# checking if w,h in range of origin(w,h)+/-5
if (face[0][2] > (origin[0][2] - threshold)) and (face[0][2] < (origin[0][2] + threshold)) and (face[0][3] > (origin[0][3] - threshold)) and (face[0][3] < (origin[0][3] + threshold)):
# check x while y is same
if face[0][1] > (origin[0][1] - threshold) and face[0][1] < (origin[0][1] + threshold):
if face[0][0] > (origin[0][0] - threshold) and face[0][0] < (origin[0][0] + threshold):
# user is in origin location
print('origin')
return 25 # no motion
else:
if (face[0][0] - origin[0][0]) > 0:
# LEFT motion event - S button
print('LEFT')
return 9
elif (face[0][0] - origin[0][0]) < 0:
# RIGHT motion event - A button
print('RIGHT')
return 8
else:
# check y while x is same
if (face[0][1] - origin[0][1]) > 0:
# DOWN motion event - Q button
print("DOWN")
mouse.scroll(0, -20)
return 6
elif (face[0][1] - origin[0][1]) < 0:
# UP motion event - W button
print('UP')
mouse.scroll(0, 20)
return 7
else:
# possible events: Zoom in, Zoom out
if (face[0][2] - origin[0][2]) > 0:
# ZOOM IN motion event - = button
mouse.scroll(0, -20)
return 4
elif (face[0][2] - origin[0][2]) < 0:
# ZOOM OUT motion event - -button
mouse.scroll(0, 20)
return 5
if __name__ == "__main__":
# print('creating window' #)
cv2.namedWindow("Video")
capture = cv2.VideoCapture(CAMERA_INDEX)
# storage = cv.CreateMemStorage()
cascade = cv2.CascadeClassifier(
cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
i = 0
c = -1
global ctr, origin, faces
faces = []
ctr = 0
origin = []
while (c == -1):
retval, image = capture.read()
# print('acq img frm' #)
# Only run the Detection algorithm every 5 frames to improve
# performance
if i % 5 == 0:
# print('calling detect' #)
ctr += 1
faces = detect_faces(image)
if(faces != [] and origin != []):
dir = get_motion(faces)
print(dir)
if ctr == 20:
# approx 3 secs of config time
origin = faces
print('origin is ', origin)
for (x, y, w, h) in faces:
# print('drawing rectangle' #)
cv2.rectangle(image,
(x, y), (x + w, y + h), 255)
# print('showing img' #)
cv2.imshow("Video", image)
# cv.ShowImage("Video", image)
i += 1
c = cv2.waitKey(10)
if(c == 27):
# escape
break
@RamiAwar
Copy link
Author

haarcascades can be found in opencv repo, just google.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment