forked from sandeshbhusal/Iris
-
Notifications
You must be signed in to change notification settings - Fork 0
/
functions.py
141 lines (131 loc) · 5.61 KB
/
functions.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
from constants import *
import cv2
import dlib
from cameraModule import *
from setup import setupCamera
from pynput.mouse import Button, Controller
import numpy as np
from imutils import face_utils
from threading import Thread
import math
import time
beginTime = time.time()
dblTime = time.time()
prevCursor = [0, 0]
class ImageProcessor:
def __init__(self):
print("--- Creating the image processor => ImageProcessor.__init__ ---")
# Setup the face cascade, camera and predictor.
# Also block the stream until image is not read
print(" Setting up camera receiving server.")
self.cam = Cam(PI_PORT, (IMAGE_WIDTH, IMAGE_HEIGHT))
print(" Setting up PI to pipe data.")
Thread(target=setupCamera()).start()
self.face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
self.predictor = dlib.shape_predictor("landmarks.dat")
print(" Please wait while the camera warms up...")
self.readFrames()
def readFrames(self):
# This function returns the facial features, as a tuple to another function
# for further processing. The function plots the tuples and makes the required mouse/
# keyboard movements as requirement.
print("Initializing face detection...")
time.sleep(10)
while True:
key = cv2.waitKey(1)
if key & 0xff == 27:
break
f = self.cam.getFrame()
if f is None:
continue
cv2.imshow("imae", f)
f = cv2.flip(f, 1)
gray = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)
cv2.equalizeHist(gray, gray)
toGuess = cv2.resize(f, (160, 120))
faces = self.face_cascade.detectMultiScale(toGuess)
mul = 4
for (x, y, w, h) in faces:
top = y*mul
left = x*mul
right = int(x+w) * mul
bottom = int(y+h) * mul
rect = dlib.rectangle(left, top, right, bottom)
shape = self.predictor(gray, rect)
shape = face_utils.shape_to_np(shape)
for (name, (i, j)) in (list(face_utils.FACIAL_LANDMARKS_IDXS.items())):
for (x, y) in shape[i:j]:
cv2.circle(f, (x, y), 1, (255, 0, 0), -1)
if name == 'nose':
noseTopPosition = shape[i:j][0]
noseBottomPosition = shape[i:j][3]
noseLeftPixel = shape[i:j][4]
noseRightPixel = shape[i:j][8]
elif name == 'left_eye':
leftEye = shape[i:j][0]
elif name == 'right_eye':
rightEye = shape[i:j][3]
toReturn = (left, top, w, h, leftEye, rightEye, noseTopPosition, noseBottomPosition, noseLeftPixel, noseRightPixel)
if MODE != "CONFIG":
processor = ProcessUI(f, toReturn)
cv2.imshow("Image", f)
break #Currently work on only one face. :)
class ProcessUI:
def __init__(self, image, faceCoordinates):
if MODE == "BROWSING":
self.offsetHolder = gamingOffset
else:
self.offsetHolder = browsingOffset
(left, top, w, h, leftEye, rightEye, noseTopPosition, noseBottomPosition, noseLeftPixel, noseRightPixel) = faceCoordinates
cv2.circle(image, (left, top), 3, (0, 255, 0), 4)
for (x,y) in faceCoordinates[4:]:
cv2.circle(image, (x,y), 2, (255, 0, 0), 3)
# cv2.imshow("Image 2", image)
mouse = Controller()
# This function gets the facial coordinates, and the input image, and makes the necessary calculations.
distanceLeft = np.array(noseTopPosition - leftEye)
unitLeft = distanceLeft
distanceRight = np.array(noseTopPosition - rightEye)
unitRight = distanceRight
distanceLeft = np.sum(distanceLeft ** 2, axis = 0)
distanceRight = np.sum(distanceRight ** 2, axis = 0)
unitLeft = unitLeft / distanceLeft ** 0.5
unitRight = unitRight / distanceRight ** 0.5
angle = np.dot(unitLeft, unitRight)
angle = math.degrees(math.acos(angle))
angle = ( angle // 2 ) * 10
topBottom = np.array(noseTopPosition - noseBottomPosition)
topBottom = (np.sum(topBottom ** 2, axis = 0)) ** 0.5
# Face top/bottom tracking using angle.
faceRatio = topBottom / h
val = (distanceLeft - distanceRight)
global prevCursor, beginTime, dblTime
x, y = mouse.position
if (x,y)==prevCursor:
if (time.time() - beginTime) > 2:
mouse.press(Button.left)
mouse.release(Button.left)
print("Click event occured")
beginTime = time.time()
if(time.time() - dblTime) > 4:
mouse.click(Button.left, 2)
print("Double click event occured")
dblTime = time.time()
else:
beginTime = time.time()
dblTime = time.time()
prevCursor=mouse.position
if abs(val) > 300:
if distanceLeft > distanceRight: #Facing right
x = x + self.offsetHolder['x']
else:
x = x - self.offsetHolder['x'] # Facing left
if angle not in range(760, 840):
if angle <= 760:
y = y - self.offsetHolder['y']
else:
y = y + self.offsetHolder['y']
mouse.position = x, y
class faceConstants:
def __init__(self):
pass