-
Notifications
You must be signed in to change notification settings - Fork 0
/
eyeglass_detector.py
executable file
·99 lines (76 loc) · 3.04 KB
/
eyeglass_detector.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
import dlib
import cv2
import numpy as np
def landmarks_to_np(landmarks, dtype="int"):
num = landmarks.num_parts
coords = np.zeros((num, 2), dtype=dtype)
for i in range(0, num):
coords[i] = (landmarks.part(i).x, landmarks.part(i).y)
return coords
def get_centers(img, landmarks):
EYE_LEFT_OUTTER = landmarks[2]
EYE_LEFT_INNER = landmarks[3]
EYE_RIGHT_OUTTER = landmarks[0]
EYE_RIGHT_INNER = landmarks[1]
x = ((landmarks[0:4]).T)[0]
y = ((landmarks[0:4]).T)[1]
A = np.vstack([x, np.ones(len(x))]).T
k, b = np.linalg.lstsq(A, y, rcond=None)[0]
x_left = (EYE_LEFT_OUTTER[0]+EYE_LEFT_INNER[0])/2
x_right = (EYE_RIGHT_OUTTER[0]+EYE_RIGHT_INNER[0])/2
LEFT_EYE_CENTER = np.array([np.int32(x_left), np.int32(x_left*k+b)])
RIGHT_EYE_CENTER = np.array([np.int32(x_right), np.int32(x_right*k+b)])
pts = np.vstack((LEFT_EYE_CENTER,RIGHT_EYE_CENTER))
cv2.polylines(img, [pts], False, (255,0,0), 1)
cv2.circle(img, (LEFT_EYE_CENTER[0],LEFT_EYE_CENTER[1]), 3, (0, 0, 255), -1)
cv2.circle(img, (RIGHT_EYE_CENTER[0],RIGHT_EYE_CENTER[1]), 3, (0, 0, 255), -1)
return LEFT_EYE_CENTER, RIGHT_EYE_CENTER
def get_aligned_face(img, left, right):
desired_w = 256
desired_h = 256
desired_dist = desired_w * 0.5
eyescenter = ((left[0]+right[0])*0.5 , (left[1]+right[1])*0.5)
dx = right[0] - left[0]
dy = right[1] - left[1]
dist = np.sqrt(dx*dx + dy*dy)
scale = desired_dist / dist
angle = np.degrees(np.arctan2(dy,dx))
M = cv2.getRotationMatrix2D(eyescenter,angle,scale)
tX = desired_w * 0.5
tY = desired_h * 0.5
M[0, 2] += (tX - eyescenter[0])
M[1, 2] += (tY - eyescenter[1])
aligned_face = cv2.warpAffine(img,M,(desired_w,desired_h))
return aligned_face
def judge_eyeglass(img):
img = cv2.GaussianBlur(img, (11,11), 0)
sobel_y = cv2.Sobel(img, cv2.CV_64F, 0 ,1 , ksize=-1)
sobel_y = cv2.convertScaleAbs(sobel_y)
#cv2.imshow('sobel_y',sobel_y)
edgeness = sobel_y
retVal,thresh = cv2.threshold(edgeness,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
d = len(thresh) * 0.5
x = np.int32(d * 6/7)
y = np.int32(d * 1/2)
w = np.int32(d * 2/7)
h = np.int32(d * 3/4)
roi = thresh[y:y+h, x:x+w]
measure = sum(sum(roi/255)) / (np.shape(roi)[0] * np.shape(roi)[1])
if measure > 0.20:
return True
else:
return False
def glasses(face,x1,y1,x2,y2):
predictor_path = "./model-weights/shape_predictor_5_face_landmarks.dat"
predictor = dlib.shape_predictor(predictor_path)
gray = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)
rects=dlib.rectangle(x1,y1,x2,y2)
landmarks = predictor(gray, rects)
landmarks = landmarks_to_np(landmarks)
LEFT_EYE_CENTER, RIGHT_EYE_CENTER = get_centers(face, landmarks)
aligned_face = get_aligned_face(gray, LEFT_EYE_CENTER, RIGHT_EYE_CENTER)
judge = judge_eyeglass(aligned_face)
if judge == True:
return 'Present'
else:
return 'Absent'