File size: 1,899 Bytes
e9565f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import cv2
import numpy as np

class FaceAnalyzer:
    def __init__(self):
        # Load OpenCV's face detector and eye detector
        self.face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
        self.eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')
        
    def _get_eye_aspect_ratio(self, eye_region):
        """
        Calculate eye aspect ratio (EAR)
        :param eye_region: Image of eye region
        :return: EAR value
        """
        # Convert eye region to grayscale
        gray_eye = cv2.cvtColor(eye_region, cv2.COLOR_BGR2GRAY)
        
        # Detect eyes
        eyes = self.eye_cascade.detectMultiScale(gray_eye)
        
        if len(eyes) != 2:  # If not detected two eyes
            return 0.0
            
        # Get eye width and height
        eye1 = eyes[0]
        eye2 = eyes[1]
        
        # Calculate eye width-height ratio
        ear1 = eye1[2] / eye1[3]
        ear2 = eye2[2] / eye2[3]
        
        # Return average EAR
        return (ear1 + ear2) / 2.0
        
    def is_drowsy(self, face_image):
        """
        Detect drowsiness
        :param face_image: Face image
        :return: Whether drowsy (True/False)
        """
        # Convert image to grayscale
        gray = cv2.cvtColor(face_image, cv2.COLOR_BGR2GRAY)
        
        # Detect faces
        faces = self.face_cascade.detectMultiScale(gray, 1.3, 5)
        
        if len(faces) == 0:
            return False
            
        # Get the largest face region
        (x, y, w, h) = faces[0]
        face_roi = face_image[y:y+h, x:x+w]
        
        # Calculate eye aspect ratio
        ear = self._get_eye_aspect_ratio(face_roi)
        
        # If EAR is less than the threshold, consider it drowsy
        EAR_THRESHOLD = 0.25
        return ear < EAR_THRESHOLD