Day 34 of 100DaysofML
Drowsiness Detector. Thought of coming up with this project based on the dlib model that I worked with in my last blog. If you are interested in this blog, please make sure to have read Day33 to understand the basics and get familiar with the installation of libraries.
So as a continuation from yesterday’s model, I am working on a Drowsiness detector which would be able to identify whenever a user is feeling drowsy or when the distance between the tip of the eyelid and the base of the eyes decreases. I shall explain a bit more about the analogy and code in the coming lines.
In the landmark detection diagram for the eyes, we may see that the points from 37–42 represent the left eye whereas the points from 43–48 represent the right eye and we are going to be using only these points and the distance between them to create the project. Have a look at the picture below which I got from the research paper which I used for this project.
Just looking at the above picture will give you a rough idea of what we are trying to implement in the given model based on distance between the eye landmarks which I have defined above.
So, essentially I’m going to work on the base code which I had mentioned yesterday so I wont be explaining that in this blog. You’d have to read yesterday’s blog for that. Anyways, I’m going to get straight to the implementation right now:
So the code is more or less same but we will be using an extra library called Distance from scipy. Now, the first step is to draw an outline around my eye and to identify the points which indicate the left as well as right eye. (I’m mentioning only the code different from yesterday’s blog and you can download the overall code from the below given github link)
for face in faces:face_landmarks = dlib_facelandmark(gray, face)
leftEye = []
rightEye = []for n in range(36,42):
x = face_landmarks.part(n).x
y = face_landmarks.part(n).y
leftEye.append((x,y))
next_point = n+1
if n == 41:
next_point = 36
x2 = face_landmarks.part(next_point).x
y2 = face_landmarks.part(next_point).y
cv2.line(frame,(x,y),(x2,y2),(0,255,0),1)for n in range(42,48):
x = face_landmarks.part(n).x
y = face_landmarks.part(n).y
rightEye.append((x,y))
next_point = n+1
if n == 47:
next_point = 42
x2 = face_landmarks.part(next_point).x
y2 = face_landmarks.part(next_point).y
cv2.line(frame,(x,y),(x2,y2),(0,255,0),1)
So basically what is happening is that we are running a loop through to see how many faces can be identified in our faces array and through the two for loops that we have, we are running them from 36 to 42 and 42 to 48 because these are the ranges of our left eye and our right eye in the given module. We are using a function to bring up the distance between the eyes which is mentioned below:
def calculate_EAR(eye):
A = distance.euclidean(eye[1], eye[5])
B = distance.euclidean(eye[2], eye[4])
C = distance.euclidean(eye[0], eye[3])
ear_aspect_ratio = (A+B)/(2.0*C)
return ear_aspect_ratio
So the function mentioned above takes the eyes and calculates the distance between the upper lid and lower lid and every time that distance crosses a threshold which in case of the above given code is 0.26, the popup shows on the screen if the user is sleepy or not. Check out the screenshots from when I ran the code. IGNORE MY FACE PLS😂.
You can check the source code int he github link given below:
I have cited the paper which I used as reference for creating this project and have mentioned the pdf below:
That’s it for today peeps. Thanks for reading. Keep Learning.
Cheers.