Python OpenCV — обнаружение сонливости

Опубликовано: 14 Декабря, 2022

Количество смертельных случаев на дороге из-за сонливости очень велико. Таким образом, Python позволяет использовать модель алгоритма глубокого обучения с использованием OpenCV. Обнаружение сонливости — это обнаружение человека для проверки того, чувствует ли он сонливость при выполнении значимой задачи. Это обнаружение имеет множество применений в области медицины и безопасности. Это обнаружение можно быстро выполнить с помощью «ориентиров лица предсказателя формы», которые отмечают основные ориентиры на лице.

Таким образом, Python также обеспечивает гибкость для обнаружения такого серьезного и значительного обнаружения с помощью модулей OpenCV. Можно легко создать собственную телефонную камеру для обнаружения сонливости с помощью приведенного ниже кода на питоне.

Необходимые шаги:

1. Установка и импорт всех необходимых для кода модулей.

1. pip install numpy    
2. pip install opencv-python
3. pip install time
4. pip install pyttsx3
5. pip install dlib
6. pip install scipy 
7. Click and Download shape_predictor_68_face_landmarks1

2. Получите доступ к камере и отметьте ориентиры из файла (.dat), чтобы предсказать расположение уха и глаз.

3. Использование функции евклидова расстояния для расчета расстояния между ориентирами на противоположных сторонах глаз. Эта функция требует наличия двух точек на плоскости для расчета расстояния.

Формула Евклидова расстояния:

4. Отметьте точки для глаз на лице, чтобы пользователю было действительно легко получить обнаружение.

5. Рассчитайте соотношение сторон для левого и правого глаза и установите критерии закрытия глаз (обнаружение сонливости).

Импорт модулей и библиотек:

import cv2
import dlib
import pyttsx3
from scipy.spatial import distance

Точки сопоставления лицевых ориентиров:

Здесь на изображении ниже показаны все маскировки и ориентиры в числовом виде для всех критических точек на нормальном лице с привязкой к правому и левому глазу соответственно.

Необходимые точки в маске для лица:

Ссылаясь на изображение выше, мы фокусируемся на правом и левом глазе и получаем все критические точки, соединяющие глаз.

Использование важных функций в программе:

  • pyttsx3.init(): эта функция используется для инициализации текста в звуковое преобразование модулей и библиотек, используемых внутри для оповещения в приведенном ниже коде.
  • VideoCapture(): эта функция используется для объявления частей камеры, используемых для OpenCV, и для включения камеры.
  • cap.read(): Храните все параметры камеры внутри функции, которые можно использовать для различных целей, например, для определения ширины, высоты канала и даже для установки цвета вывода камеры.
  • cv2.imshow(): для отображения вывода камеры, предварительно установленного пользователем. Это визуальное отображение камерой на экране.
  • dlib.shape_predictor («местоположение файла .dat»): функции ориентиров лица будут храниться внутри «файла .dat».
  • destroyAllWindow(): убить все открытые окна cv2, используемые внутри программы.
  • cap.release(): освобождает все сохраненные параметры внутри функции cap.
  • cv2.waitkey («лимит времени, установленный пользователем»): это будет держать открытым интерфейс cv2 в течение заданного времени, объявленного пользователем.
  • Detect_Eye(): функция, вычисляющая соотношение сторон глаза с помощью функции евклидова расстояния.

Пошаговая реализация

Шаг 1: Импортируйте необходимые библиотеки и их функции. И доступ к камере устройства для обнаружения лица. Инициализация pyttsx3 для звукового оповещения.

Python3




import cv2
import dlib
import pyttsx3
from scipy.spatial import distance
 
# INITIALIZING THE pyttsx3 SO THAT
# ALERT AUDIO MESSAGE CAN BE DELIVERED
engine = pyttsx3.init()
 
# SETTING UP OF CAMERA TO 1 YOU
# CAN EVEN CHOOSE 0 IN PLACE OF 1
cap = cv2.VideoCapture(1)
 
# MAIN LOOP IT WILL RUN ALL THE UNLESS
# AND UNTIL THE PROGRAM IS BEING KILLED
# BY THE USER
while True:
    null, frame = cap.read()
    gray_scale = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
    cv2.imshow("Drowsiness DETECTOR IN OPENCV2", frame)
    key = cv2.waitKey(9)
    if key == 20:
        break
cap.release()
cv2.destroyAllWindows()

Выход:

Доступ только к камере в OpenCV.

Шаг 2: Обнаружение лиц и вычисление соотношения сторон, как указано выше в формуле евклидова расстояния.

Python3




import cv2
import dlib
import pyttsx3
from scipy.spatial import distance
 
# INITIALIZING THE pyttsx3 SO THAT
# ALERT AUDIO MESSAGE CAN BE DELIVERED
engine = pyttsx3.init()
 
# SETTING UP OF CAMERA TO 1 YOU CAN
# EVEN CHOOSE 0 IN PLACE OF 1
cap = cv2.VideoCapture(1)
 
# FACE DETECTION OR MAPPING THE FACE
# TO GET THE Eye AND EYES DETECTED
face_detector = dlib.get_frontal_face_detector()
 
# PUT THE LOCATION OF .DAT FILE (FILE
# FOR PREDECTING THE LANDMARKS ON FACE )
dlib_facelandmark = dlib.shape_predictor(
    "C:\UsersAcer\Desktop\geeks\article 9\drowsinessDetector-master\shape_predictor_68_face_landmarks1.dat")
 
# FUNCTION CALCULATING THE ASPECT RATIO
# FOR THE Eye BY USING EUCLIDEAN DISTANCE
# FUNCTION
def Detect_Eye(eye):
    poi_A = distance.euclidean(eye[1], eye[5])
    poi_B = distance.euclidean(eye[2], eye[4])
    poi_C = distance.euclidean(eye[0], eye[3])
    aspect_ratio_Eye = (poi_A+poi_B)/(2*poi_C)
    return aspect_ratio_Eye
 
 
# MAIN LOOP IT WILL RUN ALL THE UNLESS AND
# UNTIL THE PROGRAM IS BEING KILLED BY THE
# USER
while True:
    null, frame = cap.read()
    gray_scale = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
    faces = face_detector(gray_scale)
 
    for face in faces:
        face_landmarks = dlib_facelandmark(gray_scale, face)
        leftEye = []
        rightEye = []
 
        # THESE ARE THE POINTS ALLOCATION FOR THE
        # LEFT EYES IN .DAT FILE THAT ARE FROM 42 TO 47
        for n in range(42, 48):
            x = face_landmarks.part(n).x
            y = face_landmarks.part(n).y
            rightEye.append((x, y))
            next_point = n+1
            if n == 47:
                next_point = 42
            x2 = face_landmarks.part(next_point).x
            y2 = face_landmarks.part(next_point).y
            cv2.line(frame, (x, y), (x2, y2), (0, 255, 0), 1)
 
        # THESE ARE THE POINTS ALLOCATION FOR THE
        # RIGHT EYES IN .DAT FILE THAT ARE FROM 36 TO 41
        for n in range(36, 42):
            x = face_landmarks.part(n).x
            y = face_landmarks.part(n).y
            leftEye.append((x, y))
            next_point = n+1
            if n == 41:
                next_point = 36
            x2 = face_landmarks.part(next_point).x
            y2 = face_landmarks.part(next_point).y
            cv2.line(frame, (x, y), (x2, y2), (255, 255, 0), 1)
 
    cv2.imshow("Drowsiness DETECTOR IN OPENCV2", frame)
    key = cv2.waitKey(9)
    if key == 20:
        break
cap.release()
cv2.destroyAllWindows()

Выход:

Примечание. Загрузите вышеуказанный файл «shape_predictor_68_face_landmarks1.dat» в ту же папку, где находится весь ваш код. И скопируйте местоположение файла и вставьте местоположение, как описано в коде.

Шаг 3: Основной цикл для чтения и сохранения параметров камеры и выделения маски для правого и левого глаза. Опишите звуковое и текстовое сообщение для пользователя, чтобы предупредить его о сонливости.

Python3




# MAIN LOOP IT WILL RUN ALL THE UNLESS AND
# UNTIL THE PROGRAM IS BEING KILLED BY
# THE USER
while True:
    null, frame = cap.read()
    gray_scale = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
    faces = face_detector(gray_scale)
 
    for face in faces:
        face_landmarks = dlib_facelandmark(gray_scale, face)
        leftEye = []
        rightEye = []
 
        # THESE ARE THE POINTS ALLOCATION FOR
        # THE LEFT EYE IN .DAT FILE THAT ARE
        # FROM 42 TO 47
        for n in range(42, 48):
            x = face_landmarks.part(n).x
            y = face_landmarks.part(n).y
            rightEye.append((x, y))
            next_point = n+1
            if n == 47:
                next_point = 42
            x2 = face_landmarks.part(next_point).x
            y2 = face_landmarks.part(next_point).y
            # LINE DRAW IN LEFT EYE
            cv2.line(frame, (x, y), (x2, y2), (0, 255, 0), 1)
 
        # THESE ARE THE POINTS ALLOCATION FOR THE
        # RIGHT EYE IN .DAT FILE THAT ARE FROM 36 TO 41
        for n in range(36, 42):
            x = face_landmarks.part(n).x
            y = face_landmarks.part(n).y
            leftEye.append((x, y))
            next_point = n+1
            if n == 41:
                next_point = 36
            x2 = face_landmarks.part(next_point).x
            y2 = face_landmarks.part(next_point).y
            # LINE DRAW IN RIGHT EYE
            cv2.line(frame, (x, y), (x2, y2), (255, 255, 0), 1)
 
        # CALCULATING THE ASPECT RATIO FOR LEFT
        # AND RIGHT EYE
        right_Eye = Detect_Eye(rightEye)
        left_Eye = Detect_Eye(leftEye)
        Eye_Rat = (left_Eye+right_Eye)/2
 
        # NOW ROUND OF THE VALUE OF AVERAGE MEAN
        # OF RIGHT AND LEFT EYES
        Eye_Rat = round(Eye_Rat, 2)
 
        # THIS VALUE OF 0.25 (YOU CAN EVEN CHANGE IT)
        # WILL DECIDE WHETHER THE PERSONS"S EYES ARE
        # CLOSE OR NOT
        if Eye_Rat < 0.25:
            cv2.putText(frame, "DROWSINESS DETECTED", (50, 100),
                        cv2.FONT_HERSHEY_PLAIN, 2, (21, 56, 210), 3)
            cv2.putText(frame, "Alert!!!! WAKE UP DUDE", (50, 450),
                        cv2.FONT_HERSHEY_PLAIN, 2, (21, 56, 212), 3)
 
            # CALLING THE AUDIO FUNCTION OF TEXT TO AUDIO
            # FOR ALERTING THE PERSON
            engine.say("Alert!!!! WAKE UP DUDE")
            engine.runAndWait()
             
    cv2.imshow("Drowsiness DETECTOR IN OPENCV2", frame)
    key = cv2.waitKey(9)
    if key == 20:
        break
cap.release()
cv2.destroyAllWindows()

Полный код:

Python3




import cv2
import dlib
import pyttsx3
from scipy.spatial import distance
 
# INITIALIZING THE pyttsx3 SO THAT
# ALERT AUDIO MESSAGE CAN BE DELIVERED
engine = pyttsx3.init()
 
# SETTING UP OF CAMERA TO 1 YOU CAN
# EVEN CHOOSE 0 IN PLACE OF 1
cap = cv2.VideoCapture(1)
 
# FACE DETECTION OR MAPPING THE FACE TO
# GET THE Eye AND EYES DETECTED
face_detector = dlib.get_frontal_face_detector()
 
# PUT THE LOCATION OF .DAT FILE (FILE FOR
# PREDECTING THE LANDMARKS ON FACE )
dlib_facelandmark = dlib.shape_predictor(
    "C:\UsersAcer\Desktop\geeks\article 9\drowsine
    ssDetector-master\shape_predictor_68_face_landmarks1.dat")
 
# FUNCTION CALCULATING THE ASPECT RATIO FOR
# THE Eye BY USING EUCLIDEAN DISTANCE FUNCTION
def Detect_Eye(eye):
    poi_A = distance.euclidean(eye[1], eye[5])
    poi_B = distance.euclidean(eye[2], eye[4])
    poi_C = distance.euclidean(eye[0], eye[3])
    aspect_ratio_Eye = (poi_A+poi_B)/(2*poi_C)
    return aspect_ratio_Eye
 
 
# MAIN LOOP IT WILL RUN ALL THE UNLESS AND
# UNTIL THE PROGRAM IS BEING KILLED BY THE USER
while True:
    null, frame = cap.read()
    gray_scale = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
    faces = face_detector(gray_scale)
 
    for face in faces:
        face_landmarks = dlib_facelandmark(gray_scale, face)
        leftEye = []
        rightEye = []
 
        # THESE ARE THE POINTS ALLOCATION FOR THE
        # LEFT EYES IN .DAT FILE THAT ARE FROM 42 TO 47
        for n in range(42, 48):
            x = face_landmarks.part(n).x
            y = face_landmarks.part(n).y
            rightEye.append((x, y))
            next_point = n+1
            if n == 47:
                next_point = 42
            x2 = face_landmarks.part(next_point).x
            y2 = face_landmarks.part(next_point).y
            cv2.line(frame, (x, y), (x2, y2), (0, 255, 0), 1)
 
        # THESE ARE THE POINTS ALLOCATION FOR THE
        # RIGHT EYES IN .DAT FILE THAT ARE FROM 36 TO 41
        for n in range(36, 42):
            x = face_landmarks.part(n).x
            y = face_landmarks.part(n).y
            leftEye.append((x, y))
            next_point = n+1
            if n == 41:
                next_point = 36
            x2 = face_landmarks.part(next_point).x
            y2 = face_landmarks.part(next_point).y
            cv2.line(frame, (x, y), (x2, y2), (255, 255, 0), 1)
 
        # CALCULATING THE ASPECT RATIO FOR LEFT
        # AND RIGHT EYE
        right_Eye = Detect_Eye(rightEye)
        left_Eye = Detect_Eye(leftEye)
     &