-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdrowsiness_detect.py
127 lines (100 loc) · 4.2 KB
/
drowsiness_detect.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
'''This script detects if a person is drowsy or not,using dlib and eye aspect ratio
calculations. Uses webcam video feed as input.'''
#Import necessary libraries
from scipy.spatial import distance
from imutils import face_utils
import numpy as np
import time
import dlib
import cv2
import os
#Minimum threshold of eye aspect ratio below which alarm is triggerd
EYE_ASPECT_RATIO_THRESHOLDS = [(0.2, 'high_drowsiness'), (0.25, 'medium_drowsiness'), (0.3, 'some_drowsiness'), (0.35, 'low_drowsiness')]
#Minimum consecutive frames for which eye ratio is below threshold for alarm to be triggered
EYE_ASPECT_RATIO_REQUIRED_FRAMES = 3
#How many images to analyze before returning not drowsy status
NUM_OF_IMAGES_IN_ONE_ANALYSIS = 6
#This function calculates and return eye aspect ratio
def eye_aspect_ratio(eye):
A = distance.euclidean(eye[1], eye[5])
B = distance.euclidean(eye[2], eye[4])
C = distance.euclidean(eye[0], eye[3])
ear = (A+B) / (2*C)
return ear
#Load face detector and predictor, uses dlib shape predictor file
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
#Extract indexes of facial landmarks for the left and right eye
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS['left_eye']
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS['right_eye']
def analyze_picture(image):
#Read each frame and flip it, and convert to grayscale
frame = cv2.flip(image, 1)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#Detect facial points through detector function
faces = detector(gray, 0)
#Detect facial points
for face in faces:
eye_aspect_ratio = get_eye_aspect_ratio(gray, face)
#Detect if eye aspect ratio is less than some threshold
for threshold, level in EYE_ASPECT_RATIO_THRESHOLDS:
if (eye_aspect_ratio < threshold):
return level
return 'no_drowsiness'
def get_eye_aspect_ratio(gray, face):
shape = predictor(gray, face)
shape = face_utils.shape_to_np(shape)
#Get array of coordinates of leftEye and rightEye
leftEye = shape[lStart:lEnd]
rightEye = shape[rStart:rEnd]
#Calculate aspect ratio of both eyes
leftEyeAspectRatio = eye_aspect_ratio(leftEye)
rightEyeAspectRatio = eye_aspect_ratio(rightEye)
eyeAspectRatio = (leftEyeAspectRatio + rightEyeAspectRatio) / 2
return eyeAspectRatio
def get_next_image(image_name):
while True:
if (os.path.exists(image_name)):
if (os.path.isfile(image_name)):
img = cv2.imread(image_name)
if img is None:
continue
else:
return img
def get_final_drowsiness_level(drowsiness_counts):
l = lambda key: drowsiness_counts[key] >= EYE_ASPECT_RATIO_REQUIRED_FRAMES
filtered = list(filter(l, drowsiness_counts.keys()))
return drowsiness_to_number(filtered[0]) if len(filtered) > 0 else 0
def drowsiness_to_number(drowsiness):
return {
'high_drowsiness': 4,
'medium_drowsiness': 3,
'some_drowsiness': 2,
'low_drowsiness': 1,
'no_drowsiness': 0
}[drowsiness]
def fresh_analyzer_state():
return {
'high_drowsiness': 0,
'medium_drowsiness': 0,
'some_drowsiness': 0,
'low_drowsiness': 0,
'no_drowsiness': 0
}
analyzer_state = fresh_analyzer_state()
image_name_generator = ((seq, "./images/image_" + str(seq) + ".jpg") for seq in range(10000000000))
while True:
for image_num, image_name in image_name_generator:
print(image_name)
# waits until next image in the sequence is found
image = get_next_image(image_name)
drowsiness_level = analyze_picture(image)
analyzer_state[drowsiness_level] += 1
# we have analysed enough images
if (image_num != 0 and image_num % NUM_OF_IMAGES_IN_ONE_ANALYSIS == 0):
drowsiness_level = get_final_drowsiness_level(analyzer_state)
with open('./images/result.txt', 'w') as f:
print("drowsiness level:", drowsiness_level)
f.write(str(drowsiness_level))
analyzer_state = fresh_analyzer_state()
os.remove(image_name)