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

Предпосылки проекта
Требованием для этого проекта Python является веб-камера, с помощью которой мы будем снимать изображения. Вам необходимо установить Python в вашей системе, прежде чем вы сможете использовать pip для установки необходимых пакетов.
- OpenCV: установить pip opencv-python
- dlib:pip install dlib (для распознавания лиц и ориентиров)
- imutils: pip install imutils
- 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)
Объем улучшения
Даже ночью мы можем обнаруживать лица с помощью тепловизора. Для этого нам нужно использовать датчики.
Приятного просмотра и спасибо за чтение!
Члены команды: Фейсал Варис, Рохит Кумар и Вишал Шарма.