Привет, Хабр! Задача контроля водителя очень актуальна в наше время. Должный контроль за состоянием водителей поможет сохранить здоровье автолюбителей, избежать многих дорожно-транспортных происшествий, тем самым снизив количество человеческих жертв.  В конце 2022 года нашей команде поступил запрос на решение данной задачи. Было необходимо предложить подходы, используя которые можно понять, насколько устал водитель, занят ли он какими-либо посторонними делами за рулем, куда он смотрит при выполнении маневров, открыты ли у него глаза (не спит ли он) и т.д. После продолжительного изучения существующих исследований в данной области, было принято решение начать работу с разработки следующих прототипов: классификатор направления взгляда водителя на основе сверточных нейронных сетей; алгоритм для оценки положения головы и ширины раскрытия глаз на основе открытых библиотек для разметки лицевых точек. Решению именно этой задачи поспособствовало следующее предположение - зная, в какую точку смотрит водитель, мы сможем: выявить особенности его поведения. Предполагается, что данные особенности будут изменяться в ходе продолжительного вождения, что может помочь определять степень усталости водителя. (источник) следить за тем, насколько правильно водитель совершает маневры - например, смотрит ли он в левое зеркало при перестроении в левый ряд.  предупреждать водителя в случаях, когда он слишком долго смотрит не по направлению движения, или когда его взгляд устремлен вниз - на спидометр и ниже, так как это будет означать, что он уснул.  Очевидно, чтобы обучить модель решить задачу классификации, необходимо найти размеченные данные. Так, нами был найден датасет Driver Gaze in the Wild, в котором представлены снимки людей, сидящих за рулем. Примеры изображений можно видеть на рисунке 1. Люди на изображениях смотрят в одну из 9 точек внутри автомобиля:  левая верхняя часть лобового стекла,  прямо перед собой,  спидометр,  радио,  правая верхняя часть лобового стекла,  правая нижняя часть лобового стекла,  правое боковое зеркало,  зеркало заднего вида,  левое боковое зеркало. Было решено использовать именно этот датасет, так как на момент начала 2023 года он является единственным доступным на просторах интернета (если существуют еще датасеты, то будем рады увидеть ссылки на них в комментариях =) ).  Датасет разделен на 3 части - train, test и val. Доступ к официальной test части получить не удалось, поэтому она была извлечена из train части. Таким образом, у частей train, val, test получились размерности: 21763, 9994, 7674 кадров и 110, 82, 40 субъектов (людей) соответственно. В статье, описывающей процесс сбора и особенности датасета, также был описан эксперимент по обучению нескольких моделей. Точности полученные авторами датасета представлены на рисунке 2. Во втором столбце значения accuracy были получены авторами путем добавления в начало нейронной сети слоя, функцией которого являлось преобразование входного изображения для минимизации влияния некоторых световых явлений (солнечных лучей, бликов) на точность классификации. Подобная предобработка может быть использована и в нашем случае. После тщательного изучения статьи в качестве базовой модели была выбрана архитектура AlexNet, так как в статье авторов датасета использовалась именно эта архитектура, да и для начала хотелось реализовать простое решения, и уже потом переходить к его улучшению, тестированию других архитектур и прочего. Проводя эксперименты с Alexnet было определено, что данная архитектура очень быстро переобучается - данных слишком мало. К тому же, точность данной нейросети по метрике accuracy составила около 54%, что явно нас не устраивало. Конечно, можно было бы применить методы авторов статьи для повышения точности. Например, использовать архитектуру Inception-V1, которая обладает наибольшим значением метрики. Однако даже точности в 61.46%, полученной авторами при использовании Inception-V1, было бы недостаточно для решения задачи контроля водителя.  Для получения более высокой точности было решено использовать предобученную на большом датасете с лицами нейросеть, а затем дообучать ее на Driver Gaze in the Wild. В качестве такой нейросети была выбрана EfficientNet-B0, предобученная на VGGFace2 и AffectNet. Модель была взята из библиотеки HSEmotion. Использование такой архитектуры позволило повысить точность с 54% до 64%, что является показателем выше, чем у базовых моделей авторов датасета.  В рамках дообучения EfficientNet-B0 было использовано несколько сочетаний гиперпараметров learning_rate, batch_size, n_epochs. Таблица с экспериментами по подбору гиперпараметров представлена по ссылке. Лучшая комбинация гиперпараметров выделена зеленым цветом. Далее для получения большей точности планировалось извлекать глаза с изображений, обучать на них сверточные сети и взвешивать предсказания полученных 3х моделей - одной, обученной на лицах, и двух других, обученных на левых и правых глазах. Потенциально, данное решение могло значительно увеличить точность классификации, так как подобное решение применили авторы статьи, и им удалось классифицировать направление взгляда на 17 точек с точностью около 82%. Более того, авторы данной работы снимали водителей с помощью инфракрасной камеры, что подтверждает возможность использования подобной архитектуры в ночных условиях. Однако в ходе тестирования обученной модели было обнаружено, что она очень чувствительна к ракурсу, с которого ведется съемка. Ее точность напрямую зависит от местоположения камеры. Для получения оптимальной точности распознавания камеру следует располагать примерно так же, как в датасете Driver Gaze in the Wild, что невозможно осуществить в каждом автомобиле. В противном случае модель неприменима. Этот неприятный факт оказался неочевидным на момент начала разработки прототипа и поспособствовал остановке работы над данным прототипом. Тем не менее, этот прототип вполне может быть использован для отслеживания направления взгляда водителя в легковых автомобилях. Для применения данного прототипа в других транспортных средствах, например, в автобусах, необходимо собирать датасет, и снова обучать нейросеть. Для реализации данного алгоритма была выбрана библиотека MediaPipe, использование которой открыто для научного и коммерческого использования. Функционал данной библиотеки позволяет размечать точки на лице человека, зная координаты которых возможно определить угол поворота головы человека по осям x и y, а также считывать такие события, как моргание/закрытие глаз. Пример разметки лицевых точек инструментами библиотеки MediaPipe можно увидеть на рисунке 3. Для расчета угла поворота головы необходимо знать: внутренние параметры камеры; коэффициенты искажений камеры; координаты лицевых точек в 2d и 3d. Внутренние параметры (intrinsic properties) и коэффициенты искажений (distortion coefficients) камеры были получены с помощью ее калибровки, используя шахматную доску и алгоритм из OpenCV под названием cv2.calibrateCamera. Координаты лицевых точек были получены средствами библиотеки MediaPipe. Получив вышеперечисленные данные, с помощью метода cv2.solvePnP были получены вектора вращения (rotation vectors), которые были переданы в метод cv2.Rodrigues для получения матрицы вращения (rotation matrix). Затем, передав матрицу вращения в метод cv2.RQDecomp3x3, были получены углы поворота головы человека в кадре. Стоит отметить, что угловая величина поворота головы довольно сильно зависит от внутренних параметров камеры. Как говорилось выше, данные параметры могут быть подобраны с помощью алгоритмов из библиотеки OpenCV путем проведения некоторых манипуляций с шахматной доской и самой камерой. Калибровку необходимо совершать на каждой камере, с помощью которой планируется съемка видео для его последующей обработки данным алгоритмом.  Закрытие глаз фиксируется через вычисление Евклидова расстояния между 4 точками вокруг каждого глаза (см. Рисунок 4), и последующего их сопоставления - рассчитывается отношение между полученными расстояниями. Если глаза закрыты - это отношение больше, если открыты - меньше. Пороговое значение может быть установлено внутри алгоритма, может подбираться в процессе калибровки при каждом запуске прототипа.  К преимуществам данного алгоритма можно отнести то, что он не чувствителен к ракурсу - при запуске алгоритма можно учитывать начальное положение человека в кадре и отсчитывать угловые величины относительно данного положения. Также к преимуществам относится его скорость работы (примерно 100 кадров в секунду), что однозначно говорит о возможности его применения в режиме реального времени. Таким образом, было разработано 2 прототипа, которые могут быть использованы при разработке системы контроля водителя за рулем. Приветствуются любые комментарии/замечания к содержанию статьи, а также идеи касательно возможных вариантов развития разработанных прототипов. Исходный код, ноутбуки, а также демонстрацию работы можно посмотреть на нашем гитхабе.   Data Scientist