1+ from scipy .spatial import distance as dist
2+ from imutils .video import FileVideoStream
3+ from imutils .video import VideoStream
4+ from imutils import face_utils
5+ import numpy as np
6+ import argparse
7+ import imutils
8+ import time
9+ import dlib
10+ import cv2
11+
12+ def eye_aspect_ratio (eye ):
13+ A = dist .euclidean (eye [1 ], eye [5 ])
14+ B = dist .euclidean (eye [2 ], eye [4 ])
15+ C = dist .euclidean (eye [0 ], eye [3 ])
16+
17+ ear = (A + B ) / (2.0 * C )
18+ return ear
19+
20+ ap = argparse .ArgumentParser ()
21+ ap .add_argument ("-p" , "--shape-predictor" , required = True ,
22+ help = "path to facial landmark predictor" )
23+ ap .add_argument ("-v" , "--video" , type = str , default = "" ,
24+ help = "path to input video file" )
25+ args = vars (ap .parse_args ())
26+
27+ EYE_AR_THRESH = 0.3
28+ EYE_AR_CONSEC_FRAMES = 3
29+
30+ COUNTER = 0
31+ TOTAL = 0
32+
33+ print ("[INFO] loading facial landmark predictor..." )
34+ detector = dlib .get_frontal_face_detector ()
35+ predictor = dlib .shape_predictor (args ["shape_predictor" ])
36+
37+ (lStart , lEnd ) = face_utils .FACIAL_LANDMARKS_IDXS ["left_eye" ]
38+ (rStart , rEnd ) = face_utils .FACIAL_LANDMARKS_IDXS ["right_eye" ]
39+
40+ print ("[INFO] starting video stream thread..." )
41+ vs = FileVideoStream (args ["video" ]).start ()
42+ fileStream = True
43+ vs = VideoStream (src = 0 ).start ()
44+ fileStream = False
45+ time .sleep (1.0 )
46+
47+ while True :
48+ if fileStream and not vs .more ():
49+ break
50+
51+ frame = vs .read ()
52+ frame = imutils .resize (frame , width = 450 )
53+ gray = cv2 .cvtColor (frame , cv2 .COLOR_BGR2GRAY )
54+
55+ rects = detector (gray , 0 )
56+
57+ for rect in rects :
58+ shape = predictor (gray , rect )
59+ shape = face_utils .shape_to_np (shape )
60+
61+ leftEye = shape [lStart :lEnd ]
62+ rightEye = shape [rStart :rEnd ]
63+ leftEAR = eye_aspect_ratio (leftEye )
64+ rightEAR = eye_aspect_ratio (rightEye )
65+
66+ ear = (leftEAR + rightEAR ) / 2.0
67+
68+ leftEyeHull = cv2 .convexHull (leftEye )
69+ rightEyeHull = cv2 .convexHull (rightEye )
70+ cv2 .drawContours (frame , [leftEyeHull ], - 1 , (0 , 255 , 0 ), 1 )
71+ cv2 .drawContours (frame , [rightEyeHull ], - 1 , (0 , 255 , 0 ), 1 )
72+
73+ if ear < EYE_AR_THRESH :
74+ COUNTER += 1
75+
76+ else :
77+ if COUNTER >= EYE_AR_CONSEC_FRAMES :
78+ TOTAL += 1
79+
80+ COUNTER = 0
81+
82+ cv2 .putText (frame , "Blinks: {}" .format (TOTAL ), (10 , 30 ),
83+ cv2 .FONT_HERSHEY_SIMPLEX , 0.7 , (0 , 0 , 255 ), 2 )
84+ cv2 .putText (frame , "EAR: {:.2f}" .format (ear ), (300 , 30 ),
85+ cv2 .FONT_HERSHEY_SIMPLEX , 0.7 , (0 , 0 , 255 ), 2 )
86+
87+ cv2 .imshow ("Frame" , frame )
88+ key = cv2 .waitKey (1 ) & 0xFF
89+
90+ if key == ord ("q" ):
91+ break
92+
93+ cv2 .destroyAllWindows ()
94+ vs .stop ()
0 commit comments