VeryNew
VeryNew

Reputation: 5

How do I play audio? (when detecting that user is asleep in front of camera)

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

Answers (0)

Related Questions