117 lines
3.3 KiB
Python
117 lines
3.3 KiB
Python
|
# Using Eye aspect ratio
|
||
|
from scipy.spatial import distance as dist
|
||
|
from imutils.video import VideoStream
|
||
|
from imutils import face_utils
|
||
|
from threading import Thread
|
||
|
import numpy as np
|
||
|
import playsound
|
||
|
import argparse
|
||
|
import imutils
|
||
|
import time
|
||
|
import dlib
|
||
|
import cv2
|
||
|
|
||
|
def sound_alarm():
|
||
|
print('You Sleep You Lose')
|
||
|
|
||
|
def eye_aspect_ratio(eye):
|
||
|
# Computes the euclidean distances between the two sets of eyes
|
||
|
A = dist.euclidean(eye[1], eye[5])
|
||
|
B = dist.euclidean(eye[2], eye[4])
|
||
|
|
||
|
# compute the euclidean distance between the horizontal
|
||
|
# eye landmark (x, y)-coordinates
|
||
|
C = dist.euclidean(eye[0], eye[3])
|
||
|
|
||
|
# compute the eye aspect ratio
|
||
|
ear = (A + B) / (2.0 * C)
|
||
|
# return the eye aspect ratio
|
||
|
return ear
|
||
|
|
||
|
shape_predictor = "../files/shape_predictor_68_face_landmarks.dat"
|
||
|
|
||
|
|
||
|
EYE_AR_THRESH = 0.2 # If the EAR goes < this for 48 frames, it is counted as drowsiness
|
||
|
EYE_AR_CONSEC_FRAMES = 48
|
||
|
|
||
|
COUNTER = 0
|
||
|
ALERT = False
|
||
|
|
||
|
# initialize dlib's face detector (HOG-based) and then create
|
||
|
# the facial landmark predictor
|
||
|
print("Initialising Facial Landmark Predictor...")
|
||
|
detector = dlib.get_frontal_face_detector()
|
||
|
predictor = dlib.shape_predictor(shape_predictor)
|
||
|
|
||
|
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
|
||
|
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
|
||
|
|
||
|
print("Starting Video Stream...")
|
||
|
vs = VideoStream(src=0).start()
|
||
|
time.sleep(1.0)
|
||
|
|
||
|
while True:
|
||
|
frame = vs.read()
|
||
|
frame = imutils.resize(frame, width=450)
|
||
|
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
||
|
|
||
|
rects = detector(gray, 0)
|
||
|
for rect in rects:
|
||
|
shape = predictor(gray, rect)
|
||
|
shape = face_utils.shape_to_np(shape)
|
||
|
|
||
|
# extract the left and right eye coordinates, then use the
|
||
|
# coordinates to compute the eye aspect ratio for both eyes
|
||
|
leftEye = shape[lStart:lEnd]
|
||
|
rightEye = shape[rStart:rEnd]
|
||
|
leftEAR = eye_aspect_ratio(leftEye)
|
||
|
rightEAR = eye_aspect_ratio(rightEye)
|
||
|
|
||
|
# average the eye aspect ratio together for both eyes
|
||
|
ear = (leftEAR + rightEAR) / 2.0
|
||
|
# compute the convex hull for the left and right eye, then
|
||
|
# visualize each of the eyes
|
||
|
leftEyeHull = cv2.convexHull(leftEye)
|
||
|
rightEyeHull = cv2.convexHull(rightEye)
|
||
|
cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
|
||
|
cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)
|
||
|
# check to see if the eye aspect ratio is below the blink
|
||
|
# threshold, and if so, increment the blink frame counter
|
||
|
if ear < EYE_AR_THRESH:
|
||
|
COUNTER += 1
|
||
|
|
||
|
# if the eyes were closed for a sufficient number of
|
||
|
# then sound the alarm
|
||
|
if COUNTER >= EYE_AR_CONSEC_FRAMES:
|
||
|
# if the alarm is not on, turn it on
|
||
|
if not ALARM_ON:
|
||
|
ALARM_ON = True
|
||
|
|
||
|
# draw an alarm on the frame
|
||
|
cv2.putText(frame, "Sleepiness Detected!", (10, 30),
|
||
|
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
|
||
|
print("Sleepiness Detected!")
|
||
|
print("\a");print("\a");print("\a");print("\a");print("\a")
|
||
|
print("\a");print("\a");print("\a");print("\a");print("\a")
|
||
|
print("\a");print("\a");print("\a");print("\a");print("\a")
|
||
|
|
||
|
|
||
|
|
||
|
else:
|
||
|
COUNTER = 0
|
||
|
ALARM_ON = False
|
||
|
|
||
|
cv2.putText(frame, "Ratio: {:.2f}".format(ear), (300, 30),
|
||
|
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
|
||
|
|
||
|
# show the frame
|
||
|
cv2.imshow("Frame", frame)
|
||
|
key = cv2.waitKey(1) & 0xFF
|
||
|
|
||
|
# if the `q` key was pressed, break from the loop
|
||
|
if key == ord("q"):
|
||
|
break
|
||
|
|
||
|
# do a bit of cleanup
|
||
|
cv2.destroyAllWindows()
|
||
|
vs.stop()
|