Причина или источник вдохновения, по которым мы выбрали именно эту тему:

Каждый день и ночь маршрутом пользуется большое количество людей. Таксисты, водители автобусов, водители грузовиков и те, кто ездит на работу на большие расстояния, лишены сна. В результате вождение в сонном состоянии чрезвычайно рискованно. Большинство аварий происходит из-за усталости водителя.

21 процент всех несчастных случаев со смертельным исходом происходит из-за вождения в сонном состоянии, что составляет более 1 миллиона аварий, поэтому, чтобы избежать этих несчастных случаев, мы выбрали именно эту тему.

Вы можете посмотреть это видео, чтобы узнать, как работает приложение.

В этом проекте Python мы создадим систему обнаружения сонливости в реальном времени для водителей, которая предупреждает их, если они засыпают из-за усталости во время вождения. Алгоритм компьютерного зрения, используемый для реализации, использует тройной подход для обнаружения сонливости, включая обнаружение лиц, измерение пропорций глаз (для обнаружения закрытых глаз) и измерение пропорций рта (для обнаружения зевоты).

Живая демонстрация



Предпосылки проекта

Требованием для этого проекта Python является веб-камера, с помощью которой мы будем снимать изображения. Вам необходимо установить Python в вашей системе, прежде чем вы сможете использовать pip для установки необходимых пакетов.

  1. OpenCV: установить pip opencv-python
  2. dlib:pip install dlib (для распознавания лиц и ориентиров)
  3. imutils: pip install imutils
  4. Pygame: pip install pygame (для воспроизведения звукового сигнала)

Давайте теперь шаг за шагом разберемся, как работает наш алгоритм.

Шаг 1. Получение изображения с камеры

С веб-камерой мы будем принимать изображения в качестве входных данных. Для доступа к веб-камере мы настраиваем бесконечный цикл, который захватывает каждый кадр. Мы используем метод, предоставленный OpenCV (cv2.waitKey(1) & 0xFF == ord(‘q’)) для доступа к камере и установки объекта захвата (шапки). cap.read() будет считывать каждый кадр, и мы сохраняем изображение в переменной кадра.

Шаг 2. Определите лицо и ориентир

Чтобы обнаружить лицо на изображении, нам нужно сначала преобразовать изображение в оттенки серого, так как алгоритм OpenCV для обнаружения объектов принимает изображения в градациях серого в качестве входных данных. Нам не нужна информация о цвете для обнаружения объектов. Мы будем использовать детектор Dlib для обнаружения лиц. Эта строка используется для установки нашего детектора faces =Detector(gray, 0). Затем мы выполняем прогноз ориентиров, используя landmarks = Predictor(gray, face). Он возвращает массив из 68 ориентиров лица.

Шаг 3. Расчет пропорций глаз и рта

Мы передадим ориентиры глаза и рта их соответствующим функциям, которые вычислят соотношение сторон для глаза и рта и вернут информацию о том, открыты ли глаза и рот или закрыты.

Функция расчета соотношения сторон глаза:

функциональная проверка Если соотношение сторон меньше 0,22, это означает, что глаза закрыты, а если оно больше 0,22, это означает, что глаза открыты.

Функция для расчета соотношения сторон рта:

функциональная проверка Если соотношение сторон меньше 0,70, это означает, что рот закрыт, а если больше 0,70, это означает, что рот открыт.

Шаг 4. Изучение различных условий

Теперь наше приложение проверяет четыре условия:

1. Если лицо не обнаружено, это означает, что водителя нет в машине, и тогда наше приложение предупредит об этом звуковым сигналом.

2. Если лицо обнаружено, но рот открыт, значит, водитель зевает. Если водитель зевает более трех раз в минуту, наше приложение воспроизводит звук, указывающий на то, что водитель устал и ему нужно отдохнуть.

3. Если какой-либо из глаз моргает, это означает, что водитель хочет спать, и приложение воспроизводит звуковой сигнал, чтобы разбудить его.

4. Если ни одно из вышеперечисленных условий не соответствует, это просто означает, что водитель не спит.

Исходный код: PythonSandbox_ Link

from flask import Flask,render_template,redirect
import cv2
import numpy as np
import dlib
from imutils import face_utils
import time
import asyncio
from pygame import mixer

app = Flask(__name__)

mixer.init()
no_driver_sound = mixer.Sound('nodriver_audio.wav')
sleep_sound = mixer.Sound('sleep_sound.wav')
tired_sound = mixer.Sound('rest_audio.wav')

# Initializing 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)

    # Checking if it is blinked
    if (ratio > 0.22):
        return 'active'
    else:
        return 'sleep'


def mouth_aspect_ratio(mouth):
    # compute the euclidean distances between the two sets of
    # vertical mouth landmarks (x, y)-coordinates
    A = compute(mouth[2], mouth[10])  # 51, 59
    B = compute(mouth[4], mouth[8])  # 53, 57

    # compute the euclidean distance between the horizontal
    # mouth landmark (x, y)-coordinates
    C = compute(mouth[0], mouth[6])  # 49, 55

    # compute the mouth aspect ratio
    mar = (A + B) / (2.0 * C)

    # return the mouth aspect ratio
    return mar


(mStart, mEnd) = (49, 68)


async def tired():
    start = time.time()
    rest_time_start=start
    tired_sound.play()
    a = 0
    while (time.time()-start < 9):
        if(time.time()-rest_time_start>3):
            tired_sound.play()
        # cv2.imshow("USER",tired_img)
    tired_sound.stop()
    return


def detech():
    # status marking for current state
    sleep_sound_flag = 0
    no_driver_sound_flag = 0
    yawning = 0
    no_yawn = 0
    sleep = 0
    active = 0
    status = ""
    color = (0, 0, 0)
    no_driver=0
    frame_color = (0, 255, 0)
    # Initializing the camera and taking the instance
    cap = cv2.VideoCapture(0)

    # Give some time for camera to initialize(not required)
    time.sleep(1)
    start = time.time()
    no_driver_time=time.time()
    no_driver_sound_start = time.time()

    while True:
        _, frame = cap.read()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        face_frame = frame.copy()
        faces = detector(gray, 0)

        # detected face in faces array
        if faces:
         no_driver_sound_flag=0   
         no_driver_sound.stop()   
         no_driver=0  
         no_driver_time=time.time() 
        #  sleep_sound.stop()
         for face in faces:
            x1 = face.left()
            y1 = face.top()
            x2 = face.right()
            y2 = face.bottom()

            cv2.rectangle(frame, (x1, y1), (x2, y2), frame_color, 2)
            # cv2.rectangle(face_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])
            mouth = landmarks[mStart:mEnd]
            mouthMAR = mouth_aspect_ratio(mouth)
            mar = mouthMAR

            # Now judge what to do for the eye blinks

            if (mar > 0.70):
                sleep = 0
                active = 0
                yawning += 1
                status = "Yawning"
                color = (255, 0, 0)
                frame_color = (255, 0, 0)
                sleep_sound_flag = 0
                sleep_sound.stop()

            elif (left_blink == 'sleep' or right_blink == 'sleep'):
                if (yawning > 20):
                    no_yawn += 1
                sleep += 1
                yawning = 0
                active = 0
                if (sleep > 5):
                    status = "Sleeping !"
                    color = (0, 0, 255)
                    frame_color = (0, 0, 255)
                    if sleep_sound_flag == 0:
                        sleep_sound.play()
                    sleep_sound_flag = 1
            else:
                if (yawning > 20):
                    no_yawn += 1
                yawning = 0
                sleep = 0
                active += 1
                status = "Awake"
                color = (0, 255, 0)
                frame_color = (0, 255, 0)
                if active > 5:
                    sleep_sound_flag = 0
                    sleep_sound.stop()

            cv2.putText(frame, status, (50, 50),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.75, color, 2)

            if (time.time()-start < 60 and no_yawn >= 3):
                no_yawn = 0
                # print("tired")
                # asyncio.run(put_image(frame))
                # time.sleep(2)
                asyncio.run(tired())
            elif time.time()-start > 60:
                start = time.time()

            for n in range(0, 68):
                (x, y) = landmarks[n]
                cv2.circle(face_frame, (x, y), 1, (255, 255, 255), -1)
        else:
            no_driver+=1
            sleep_sound_flag = 0
            sleep_sound.stop()
            if(no_driver>10):
              status="No Driver"
              color=(0,0,0)
            if time.time()-no_driver_time>5:
                if(no_driver_sound_flag==0):
                   no_driver_sound.play()
                   no_driver_sound_start=time.time()
                else:
                    if(time.time()-no_driver_sound_start>3):
                        no_driver_sound.play()
                        no_driver_sound_start=time.time()
                no_driver_sound_flag=1

        cv2.putText(frame, status, (50, 50),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.75, color, 2)
        cv2.imshow("DRIVER (Enter q to exit)", frame)
        cv2.imshow("68_POINTS", face_frame)
        if (cv2.waitKey(1) & 0xFF == ord('q')):
            break
    no_driver_sound.stop()
    sleep_sound.stop()
    tired_sound.stop()
    cap.release()
    cv2.destroyAllWindows()   

@app.route("/open_camera")
def open():
    detech()
    print("open camera")
    return redirect("/")

@app.route("/")
def home():
    return render_template("index.html")


if __name__ == "__main__":
    app.run(debug=True)

Объем улучшения

Даже ночью мы можем обнаруживать лица с помощью тепловизора. Для этого нам нужно использовать датчики.

Приятного просмотра и спасибо за чтение!

Члены команды: Фейсал Варис, Рохит Кумар и Вишал Шарма.