Обнаружение сонливости водителя продиктовано потребностью безопасности – разработка приложения для обнаружения в режиме реального времени позволит избежать серьезных происшествий в тот момент, когда водитель переутомлен. По разным оценкам, около 20% всех уличных происшествий связаны с переутомлением, а на некоторых оживленных улицах – до 50%. Таким образом, совершенствование технологий распознавания и предотвращения сна за рулем может стать серьезным вызовом в области улучшения систем предотвращения аварий. При обнаружении сонливости, необходимо в тот же момент предупредить водителя о возможных неприятностях. Подобное обнаружение достигается при помощи детектирования состояния глаз водителя.

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

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

Классификация состояния глаз осуществляется при помощи методов компьютерного зрения. Чтобы начать реализацию, необходимо создать новый *.py-файл, открыть его в текстовом редакторе или среде разработки для языка Python (например, в IDLE) и выполнить подключение необходимых библиотек. Исходный код функции воспроизведения приведен в листинге 1.

Листинг 1. Функция воспроизведения уведомления
def runAlarm(path):
	# воспроизвести уведомление
	playsound.playsound(path)

Далее необходимо определить функцию findEAR, которая используется для вычисления отношения расстояний между вертикальными признаками глаза и расстояниями между горизонтальными признаками глаза (листинг 2).

Листинг 2. Функция вычисления EAR
def findEAR(eye):
	# вычислить евклидовы расстояния между двумя наборами
	# вертикальных признаков глаза (x, y)-координат
	A = dist.euclidean(eye[1], eye[5])
	B = dist.euclidean(eye[2], eye[4])
	# то же самое для горизонтальных признаков
	C = dist.euclidean(eye[0], eye[3])
	# вычислить EAR
	ear = (A + B) / (2.0 * C)
	# вернуть его
	return ear

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

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

Рисунок 1 – Визуализация глазных ориентиров. Вверху слева: глаз открыт. Вверху справа: глаз закрыт. Внизу: график соотношения сторон с течением времени. Падение соотношения сторон глаза указывает на моргание.

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

Листинг 3. Пороговые значения 
# определить две константы:
# одну для соотношения сторон глаза, чтобы определить моргание,
# а затем вторую константу для количества последовательных кадров.
# глаз должен быть ниже порогового значения, чтобы сработал сигнал тревоги
THRESHOLD_EAR = 0.3
FRAMES_EAR = 48
# инициализировать счетчик кадров, а также логическое значение,
# используемое для индикации срабатывания сигнализации
COUNTER = 0
ALARM_ON = False

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

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

Экспериментально было обнаружено, что значение THRESHOLD_EAR, равное 0,3, хорошо работает в различных ситуациях.

Значение FRAMES_EAR также экспериментально было установлено на 48 – если человек закрывает глаза на 48 последовательных кадров, то будет воспроизводиться звуковой сигнал. Можно сделать детектор более чувствительным, уменьшив FRAMES_EAR – аналогично, менее чувствительным, увеличив его.

В листинге 3 также определена переменная COUNTER – общее количество последовательных кадров, на протяжении которых соотношение сторон глаза меньше THRESHOLD_EAR. Если COUNTER превышает FRAMES_EAR, то следует обновить логическое значение ALARM_ON. Библиотека dlib поставляется с детектором лица на основе гистограммы ориентированных градиентов вместе с предсказателем лицевых признаков. Соответствующие экземпляры создаются в следующем блоке кода (листинг 4).

Листинг 4. Детектор лица и предсказатель признаков лица
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])

Признаки (ориентиры) лица, созданные dlib, представляют собой индексируемый список (рисунок 2). Следовательно, чтобы извлечь области глаз из набора лицевых признаков, необходимо знать правильные индексы срезов массива (листинг 5).

Листинг 5. Выделение индексов признаков глаз
(leftEyeSt, leftEyeEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rightEyeSt, rightEyeEnd) = face_utils. FACIAL_LANDMARKS_IDXS["right_eye"]

Используя эти индексы, можно легко выделить области глаз с помощью списковых срезов. Теперь можно запустить ядро ​​детектора сонливости (листинг 6).

Рисунок 2 – Визуализация лицевых признаков.

Листинг 6. Запуск детектора сонливости водителя
# запустить захват видеопотока с веб-камеры
vs = VideoStream(src=args["webcam"]).start()
time.sleep(1.0)

# цикл по кадрам из видеопотока
while True:
	# захватить кадр из потокового видеофайла, изменить его размер
        # и преобразовать в каналы в оттенки серого
	frame = vs.read()
	frame = imutils.resize(frame, width=450)
	gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

	# обнаружить лица при помощи детектора
	rects = detector(gray, 0)

Вначале создается экземпляр потока VideoStream, который использует индекс веб-камеры ноутбука для захвата видео. Также здесь необходимо сделать паузу на одну секунду, чтобы дать сенсору камеры включиться. В цикле считываются кадры видеопотока один за другим, и затем они подвергаются предварительной обработке (размер каждого кадра изменяется до ширины 450 пикселей; каждый кадр преобразуется в оттенки серого). Детектор лиц dlib применяется для поиска и определения местоположения лица (лиц) на изображении.

Следующим шагом будет применение функции распознавания признаков на лице, чтобы локализовать каждую из важных областей лица. Каждое из обнаруженных лиц перебирается в цикле (на самом деле предполагается, что есть только одно лицо – водителя, но этот цикл может быть использован для видео с более чем одним лицом). Для каждого из обнаруженных лиц применяется детектор лицевых признаков dlib, и результат преобразуется в numpy-массив. Используя срезы массива, можно извлечь (x, y)-координаты левого и правого глаза соответственно. Зная (x, y)-координаты для обоих глаз, легко затем вычислить их соотношения сторон. Для лучшей оценки эти значения усредняются. Затем можно визуализировать каждую из областей глаз на кадре с помощью функции cv2.drawContours – это часто бывает полезно, когда необходимо убедиться, что глаза правильно обнаруживаются и локализуются.

Наконец, все готово для того, чтобы можно было проверить, не начинает ли водитель в видеопотоке проявлять симптомы сонливости.

Вначале проверяется, находится ли соотношение сторон глаза ниже порога «blink / closed» («моргание / закрытие»).

Если это так, то увеличивается счетчик, общее количество последовательных кадров, в которых у водителя были закрыты глаза.

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

Далее выполняется еще одна проверка, чтобы увидеть, включен ли звуковой сигнал – если нет, то он включается.

Затем обрабатывается воспроизведение звукового сигнала при условии, что при выполнении скрипта был указан путь к файлу —alarm. Особое внимание здесь уделяется созданию отдельного потока, отвечающего за вызов звукового сигнала, чтобы гарантировать, что основная программа не заблокируется до тех пор, пока не закончится воспроизведение звука.

После этого в кадре отображается текст «DROWSINESS ALERT!» («ПРЕДУПРЕЖДЕНИЕ О СОНЛИВОСТИ»).

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

При использовании классификатора сначала настраивается камера, которая отслеживает все лица на видеокадре из потока (рисунок 3).

Рисунок 3 – Поиск лиц во входном видеопотоке.

Если лицо найдено, то выполняется определение признаков глаз на лице и извлекаются области глаз (рисунок 4).

Рисунок 4 – Выделение глаз на лице водителя.

Теперь, когда на кадре выделены области глаз, можно вычислить соотношение сторон глаза (EAR – Eye Aspect Ratio), чтобы определить, закрыты ли глаза (рисунок 5).

Рисунок 5 – Вычисление EAR.

Если соотношение сторон глаза указывает на то, что глаза были закрыты достаточно долгое время, то вызывается звуковое уведомление, предназначенное для того, чтобы разбудить уснувшего водителя (рисунок 6).

Рисунок 6 – Вызов звукового уведомления.

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

Детектор сонливости может работать в различных условиях, в том числе под прямыми солнечными лучами при движении по дороге и при слабом или искусственном освещении в бетонном гараже.  На данный момент у разработанного приложения обнаруживается несколько ограничений. Самое большое из них – неспособность обнаружить глаза при слабом освещении. Большинство случаев сонливости приходится на ночное время, и эффективность программы в темноте невысока. Другим ограничением является задержка по времени между счетом, в течение которого глаза были закрыты, и сигналом тревоги. За счет использования более качественного оборудования можно повысить общую эффективность системы.

Комментарии (11)


  1. Ryav
    06.10.2021 08:32

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

    Ну так вряд ли камера будет чётко напротив лица, скорее всего со стороны зеркала заднего вида.


    1. NewTechAudit Автор
      07.10.2021 11:37

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


  1. berkot
    07.10.2021 11:59

    К сожалению водитель может "заснуть" и с полностью открытыми глазами. Спустя какое-то время за рулём попросту теряется концентрация и способность оценивать окружающую обстановку. Именно поэтому такие комплексы прежде всего оценивают воздействие водителя на органы управления автомобиля, их частоту и или смену характера.


    1. NewTechAudit Автор
      07.10.2021 12:00

      Добрый день! Да может, но для случаев с обычным засыпанием водителя с закрытыми глазами (которых большинство), данная система будет работать.


  1. alferiusgmailcom
    07.10.2021 12:01

    Реализация есть? Или это только теоретические выкладки?


    1. NewTechAudit Автор
      07.10.2021 12:04

      Добрый день! Детектор сонливости может работать в различных условиях, в том числе под прямыми солнечными лучами при движении по дороге и при слабом / искусственном освещении в бетонном гараже.

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

      На данный момент у разработанного приложения есть много ограничений. Самое большое из них – неспособность обнаружить глаза при слабом освещении. Большинство случаев сонливости случается ночью, и эффективность программы в темноте невысока. Другим ограничением является задержка по времени между счётом времени, в течение которого глаза были закрыты, и сигналом тревоги. За счёт включения более качественного оборудования можно повысить общую эффективность системы.

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


  1. alferiusgmailcom
    07.10.2021 12:15

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


    1. NewTechAudit Автор
      07.10.2021 15:02

      Идея хорошая, можно попробовать использовать данное решение в следующих тестах.


  1. phinish
    07.10.2021 15:00

    Камера в салоне - так себе идея, в свете https://habr.com/ru/company/luxoft/blog/580702/. Были попытки внедрить функцию распознавания усталости водителя по изменению "стиля" его воздействия на органы управления. Получилось не очень.

    Реально помогает функция контроля движения по полосе, она будит водителя вибрацией руля или резким торможением (если первое не сработает). Для этого, правда, нужна видимая разметка на дорожном полотне.


    1. NewTechAudit Автор
      07.10.2021 15:01

      Добрый день! Почти у всех систем для борьбы с сонливостью есть те или иные недостатки. Отслеживание полосы не будет работать на дорогах без разметки, отслеживание характера езды тоже будет иметь погрешности, т.к. есть водители достаточно агрессивные, а есть люди которые только что получили права и опыта ещё совсем мало для быстрой реакции на происходящее на дороге. Я думаю максимальную пользу можно извлечь при использовании всех этих методов в совокупности.


  1. DOTsDev
    17.11.2021 09:06

    буквально три недели назад в питере на Neva2021 был стенд с китайцами на данную тему. Специально упакованный копм, ик. посветка, GPU, ревун там для водителя.. Ну и аналитика всяких чихов вздохов, зевков, времени в пути, темное время и.т.п короче очень добротно. Не помню названия, но сказали что на магистральных автобусных перевозках уже внедряют в рф.