-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patheyeball_tracking_own.py
128 lines (98 loc) · 3.58 KB
/
eyeball_tracking_own.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
import cv2
import dlib
import numpy as np
# 用來顯示的函示庫
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# init part
FACE_CASCADE = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
EYES_CASCADE = cv2.CascadeClassifier('haarcascade_eye_tree_eyeglasses.xml')
detector_params = cv2.SimpleBlobDetector_Params()
detector_params.filterByArea = True
detector_params.maxArea = 1500
detector = cv2.SimpleBlobDetector_create(detector_params)
# 建立人臉細節偵測
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 臉部偵測
def detect_faces(img, cascade):
gray_frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
coords = cascade.detectMultiScale(gray_frame, 1.3, 5)
if len(coords) > 1:
biggest = (0, 0, 0, 0)
for i in coords:
if i[3] > biggest[3]:
biggest = i
biggest = np.array([i], np.int32)
elif len(coords) == 1:
biggest = coords
else:
return None
for (x, y, w, h) in biggest:
frame = img[y:y + h, x:x + w]
return frame
def detect_eyes(img, cascade):
gray_frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
eyes = cascade.detectMultiScale(gray_frame, 1.3, 5) # detect eyes
width = np.size(img, 1) # get face frame width
height = np.size(img, 0) # get face frame height
left_eye = None
right_eye = None
for (x, y, w, h) in eyes:
if y > height / 2:
pass
eyecenter = x + w / 2 # get the eye center
if eyecenter < width * 0.5:
left_eye = img[y:y + h, x:x + w]
else:
right_eye = img[y:y + h, x:x + w]
return left_eye, right_eye
def cut_eyebrows(img):
height, width = img.shape[:2]
eyebrow_h = int(height / 4)
img = img[eyebrow_h:height, 0:width] # cut eyebrows out (15 px)
return img
def blob_process(img, threshold, detector):
gray_frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, img = cv2.threshold(gray_frame, threshold, 255, cv2.THRESH_BINARY)
img = cv2.erode(img, None, iterations=2)
img = cv2.dilate(img, None, iterations=4)
img = cv2.medianBlur(img, 3)
keypoints = detector.detect(img)
print(keypoints)
return keypoints
def nothing(x):
pass
# 將特徵點的座標給儲存下來
def shape_to_np(shape, dtype = "int"):
# initialize the list of (x, y)-coordinates
coords = np.zeros((68, 2), dtype = dtype)
# loop over the 68 facial landmarks and convert them
# to a 2-tuple of (x, y)-coordinates
for i in range(0, 68):
coords[i] = (shape.part(i).x, shape.part(i).y)
# return the list of (x, y)-coordinates
return coords
def main():
cap = cv2.VideoCapture(0)
cv2.namedWindow('image')
cv2.createTrackbar('threshold', 'image', 0, 255, nothing)
while True:
_, frame = cap.read()
face_frame = detect_faces(frame, FACE_CASCADE)
if face_frame is not None:
eyes = detect_eyes(face_frame, EYES_CASCADE)
for eye in eyes:
# 判斷是否有找到眼睛
if eye is not None:
threshold = r = cv2.getTrackbarPos('threshold', 'image')
eye = cut_eyebrows(eye)
keypoints = blob_process(eye, threshold, detector)
eye = cv2.drawKeypoints(eye, keypoints, eye, (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow('image', frame)
# 離開迴圈,關閉攝影機
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()