-
-
Save anishg24/01c4f02afd006d25cff275589800b994 to your computer and use it in GitHub Desktop.
Attention Detection with OpenCV and DLib
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from scipy.spatial import distance as dist | |
from imutils.video import VideoStream | |
from imutils import face_utils | |
from threading import Thread | |
import playsound | |
import argparse | |
import imutils | |
import time | |
import dlib | |
import cv2 | |
def sound_alarm(path): | |
playsound.playsound(path) | |
def eye_aspect_ratio(eye): | |
A = dist.euclidean(eye[1], eye[5]) | |
B = dist.euclidean(eye[2], eye[4]) | |
C = dist.euclidean(eye[0], eye[3]) | |
# find the eye aspect ratio, NOT an ear that is used for hearing | |
ear = (A + B) / (2.0 * C) | |
return ear | |
ap = argparse.ArgumentParser() | |
ap.add_argument("-p", "--shape-predictor", required=True, | |
help="path to facial landmark predictor") | |
ap.add_argument("-a", "--alarm", type=str, default="", | |
help="path alarm .WAV file") | |
ap.add_argument("-w", "--webcam", type=int, default=0, | |
help="index of webcam on system") | |
args = vars(ap.parse_args()) | |
EYE_AR_THRESH = 0.3 | |
EYE_AR_CONSEC_FRAMES = 48 | |
COUNTER = 0 | |
ALARM_ON = False | |
print("Loading facial landmarks predictor...") | |
detector = dlib.get_frontal_face_detector() | |
predictor = dlib.shape_predictor(args["shape_predictor"]) | |
print("Loaded!") | |
(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=args["webcam"]).start() | |
time.sleep(1.0) | |
print("Started!") | |
while True: | |
real_frame = vs.read() | |
frame = imutils.resize(real_frame, width=450) | |
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) | |
rects = detector(gray, 0) | |
if not rects: | |
cv2.putText(frame, "NO EYES FOUND! FOCUS UP!", (10, 30), | |
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) | |
for rect in rects: | |
shape = predictor(gray, rect) | |
shape = face_utils.shape_to_np(shape) | |
leftEye = shape[lStart:lEnd] | |
rightEye = shape[rStart:rEnd] | |
leftEAR = eye_aspect_ratio(leftEye) | |
rightEAR = eye_aspect_ratio(rightEye) | |
ear = (leftEAR + rightEAR) / 2.0 | |
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) | |
if ear < EYE_AR_THRESH: | |
COUNTER += 1 | |
if COUNTER >= EYE_AR_CONSEC_FRAMES: | |
if not ALARM_ON: | |
ALARM_ON = True | |
if args["alarm"] != "": | |
t = Thread(target=sound_alarm, | |
args=(args["alarm"],)) | |
t.deamon = True | |
t.start() | |
cv2.putText(frame, "PAY ATTENTION!", (10, 30), | |
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) | |
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) | |
real_frame = imutils.resize(real_frame, width=450) | |
cv2.imshow("Live Stream Frame", real_frame) | |
cv2.imshow("Computer Vision Frame", frame) | |
key = cv2.waitKey(1) & 0xFF | |
if key == ord("q"): | |
break | |
cv2.destroyAllWindows() | |
vs.stop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment