Reputation: 5
Im trying to create a sleep detection website and its supposed to play an alarm when the user is detected to be asleep. I am using opencv and dlib to do the eye and face detection. The user would be considered to be asleep if their eyes are closed. I have managed to use flask to display a live stream of my webcam on a website but I am having problems making it play an alarm when the user is asleep.
This is my code for the python part:
from flask import Flask, render_template, Response
import cv2
import numpy as np
from imutils import face_utils
import dlib
import winsound
from playsound import playsound
app = Flask(__name__)
camera = cv2.VideoCapture(0)
#Initialise the face detector and landmark detector
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
def compute(ptA, ptB):
dist = np.linalg.norm(ptA - ptB)
return dist
def blinked(a, b, c, d, e, f):
up = compute(b,d) + compute(c,e)
down = compute(a,f)
ratio = up/(2.0*down)
#Check if user blinked
if(ratio > 0.25):
return 2
elif(ratio > 0.21 and ratio <= 0.25):
return 1
else:
return 0
def gen_frames():
while True:
#read the camera frames
success, frame = camera.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if not success:
break
else:
#status marking for current state
sleep = 0
drowsy = 0
active = 0
status = ""
color = (0, 0, 0)
faces = detector(gray)
# detected face in faces array
for face in faces:
x1 = face.left()
y1 = face.top()
x2 = face.right()
y2 = face.bottom()
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
landmarks = predictor(gray, face)
landmarks = face_utils.shape_to_np(landmarks)
# The numbers are actually the landmarks which will show eye
left_blink = blinked(landmarks[36], landmarks[37],
landmarks[38], landmarks[41], landmarks[40], landmarks[39])
right_blink = blinked(landmarks[42], landmarks[43],
landmarks[44], landmarks[47], landmarks[46], landmarks[45])
# Now judge what to do for the eye blinks
if(left_blink == 0 or right_blink == 0):
sleep += 1
drowsy = 0
active = 0
if(sleep > 6):
status = "SLEEPING !!!"
color = (255, 0, 0)
# playsound('alarm.wav')
#winsound.PlaySound('alarm.wav', winsound.SND_FILENAME)
elif(left_blink == 1 or right_blink == 1):
sleep = 0
active = 0
drowsy += 1
if(drowsy > 6):
status = "Drowsy !"
color = (0, 0, 255)
else:
drowsy = 0
sleep = 0
active += 1
if(active > 6):
status = "Active :)"
color = (0, 255, 0)
cv2.putText(frame, str(status), (100, 100),
cv2.FONT_HERSHEY_SIMPLEX, 1.2, color, 3)
# flippedFrame = cv2.flip(frame, 1)
for n in range(0, 68):
(x, y) = landmarks[n]
cv2.circle(frame, (x, y), 1, (255, 255, 255), -1)
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
yield(b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame +
b'\r\n')
@app.route('/')
def index():
return render_template('index.html')
@app.route('/video')
def video():
return Response(gen_frames(), mimetype='multipart/x-mixed-replace;
boundary=frame')
if __name__ == "__main__":
app.run(debug=True)
And this is my code for the html part:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=<device-width>, initial-scale=1.0">
<title>SleepCatcher</title>
</head>
<body>
<!-- Video Stream -->
<div id="video">
<img src="{{ url_for('video') }}" />
</div>
</body>
</html>
Is there a way to play an audio when the user is detected to be asleep and then stop playing the audio when theyre detected to be awake? The way i can think of is to pass the sleep status from gen_frames() to the flask Response in video so that I can access the sleep status on the html side and play the alarm but it feels like there should be another way to do it.
Thank you in advance! :)
Upvotes: 0
Views: 81