И снова о распознавании лиц с помощью Python
Технологии распознавания лиц уже активно используется для решения различных задач, от поиска преступников до применения в качестве идентификатора личности при осуществлении платежей.
При этом, о различных системах распознавания лиц написано множество публикаций. В этой статье мы посмотрим, как можно использовать библиотеки OpenCV и Dlib для распознавания лиц.
Мы не будем сильно углубляться в код, а вместо этого посмотрим рабочие примеры систем распознавания на основе этих библиотек.
При распознавании нас интересует только определение того, какие части изображения являются человеческими лицами. То есть, по сути, нам необходимо выделить из всего изображения только тот квадрат, который, по мнению системы распознавания, и является лицом.
Такие библиотеки, как OpenCV и Dlib, предоставляют классификаторы с открытым исходным кодом, которые можно использовать с минимальными настройками.
Существующие классификаторы HaarCascade и Dlib, которые мы далее будем использовать, могут обнаруживать лица с достаточно высокой степенью точности.
Готовим инструментарий
Для начала давайте подготовим среду для наших экспериментов. Здесь нам потребуется операционная система с оконным интерфейсом, для того, чтобы видеть результаты распознавания. Я использовал Ubuntu Desktop 24.04.
Так как мы будем использовать pip для установки необходимых компонентов, необходимом заранее подготовить среду:
$ sudo apt update
$ sudo install pipenv
$ pipenv shell
Далее необходимо клонировать репозиторий с кодом и примерами
$ git clone
https://github.com/nirdosh17/computer-vision-examples
И собственно выполнить установку:
$ cd computer-vision-examples
$ make install
После этого pip начнет установку нужных пакетов. На шаге сборки dlib установщик может подвиснуть на 10–15 минут. Пусть вас это не смущает, потом все должно успешно ожить и установиться.
Для того, чтобы убедиться в успешности установки можно выполнить make help
, он покажет список доступных команд для запуска алгоритмов обнаружения и распознавания лиц.
Теперь поговорим о принципах работы самих классификаторов.
HaarCascade
Начнем с классификатора HaarCascade. Это достаточно простой и быстрый классификатор, в описании его рекомендуют использовать в том числе, на микрокомпьютерах Raspberry Pi.
При этом, как мы дальше убедимся, он менее точен, чем Dlib, поэтому требует небольшой настройки для получения более точных результатов. В этой статье мы говорим о распознавании лиц, но HaarCascade можно также использовать для распознавания номерных знаков, домашних животных и многого другого.
В основу принципа работы данного классификатора положено обнаружение объектов с помощью каскадных классификаторов на основе функций Хаара. Это подход, основан на машинном обучении, при котором каскадная функция обучается на множестве положительных и отрицательных изображений. Затем она используется для обнаружения объектов на других изображениях.
Так, изначально для обучения классификатора требуется множество положительных (изображения лиц) и отрицательных (изображения без лиц) изображений. Затем нам нужно извлечь из них признаки (признаки Хаара), показанные на рисунке ниже. Каждый признак — это одно значение, полученное путем вычитания суммы пикселей под белым прямоугольником из суммы пикселей под черным прямоугольником.

Для вычисления каждого признака нам нужно найти сумму пикселей под белыми и черными прямоугольниками. Чтобы решить эту проблему, вводится понятие интегрального изображения. То есть, каким бы большим ни было наше изображение, его обработка сводится к операции, включающей всего четыре пикселя.
Но проблема заключается в том, что среди всех этих признаков, которые мы просчитали, большинство не имеет никакого значения. Нам необходимо найти оптимальный порог, который позволяет классифицировать признаки лиц как подходящие или нет (положительный и отрицательный результат. Очевидно, что при этом будут возникать ошибки или неверные классификации. Мы выбираем признаки с минимальным коэффициентом ошибок, то есть те, которые наиболее точно классифицируют изображения лиц и не лиц.
Процесс не так прост. Вначале каждому изображению присваивается одинаковый вес. После каждой классификации веса неправильно классифицированных изображений увеличиваются. Затем выполняется тот же процесс. Вычисляются новые коэффициенты ошибок. Также рассчитываются новые веса. Процесс продолжается до тех пор, пока не будет достигнута требуемая точность или коэффициент ошибок, или пока не будет найдено необходимое количество признаков.
Окончательный классификатор представляет собой взвешенную сумму этих слабых классификаторов. Он называется слабым, потому что сам по себе не может классифицировать изображение, но вместе с другими образует сильный классификатор. Их конечная система насчитывала около 6000 признаков.
На изображении большая часть — это область, не содержащая лиц. Поэтому лучше иметь простой метод проверки, не является ли часть изображения областью лица. Если это не так, отбросьте его за один снимок и не обрабатывайте его снова. Вместо этого сосредоточьтесь на областях, где может быть лицо. Таким образом, мы тратим больше времени на проверку возможных областей лица.
Для борьбы с этим используется концепция каскада классификаторов. Вместо того чтобы применять все 6000 признаков к области, признаки группируются в различные этапы классификаторов и применяются поочередно. Если область не прошла первый этап, мы отбрасываем его. Оставшиеся в нем признаки мы не рассматриваем. Если она прошла, применяем второй этап и продолжаем процесс. Область, прошедшая все этапы, является областью лица.
На этом с занудной полезной теорией можно закончить и приступить к практике.
Для начала можно распознать тестовое изображение, которое уже есть в классификаторе. Для этого выполним:
$ make haar-detect

Как видно, все прекрасно распозналось. Однако, это не очень интересный пример. Попробуем распознать лица на изображении найденном в сети. Для этого нужно передать параметр TEST_IMAGE с именем анализируемого файла.
$ make haar-detect TEST_IMAGE=”имя_файла”

Как видно, HaarCascade распознал не все лица на изображении.
Можно попробовать дообучить модель, добавив несколько подобных (но естественно, не таких же) изображений в учебный набор, находящийся в каталоге datasets/faces.
Для того, чтобы включить режим обучения в описании проекта, предлагается в папке faces создать каталоги с именами каждого, изображенного на рисунке и поместить в них фото соответствующего человека. В таком случае система не просто распознает лица, но и сможет «узнать человека».
Далее, для запуска обучения выполним:
$ make haar-train
make haar-recognize
make haar-recognize TEST_IMAGE="имя_файла"
В результате получаем результаты обучения и изображение с процентами совпадения.

Здесь показано обучение на наборе изображений, входящих в состав классификатора, но также можно создать свои наборы для обучения.
Также HaarCascade позволяет находить изображения в видеопотоках. Для этого необходимо выполнить:
$ make live-detect
Dlib
Второе решение, входящее в наш инструмент для распознавания лиц — это библиотека Dlib. Она умеет делать множество различных операций для машинного обучения и распознавания изображений. Нас будет интересовать использование алгоритмов MMOD CNN и HOG.
Алгоритм распознавания лиц MMOD CNN, который использует выделение лицевых ориентиров для масштабирования, вращения и центрирования исходного изображения. Алгоритм устойчив к изменениям поворота лица и угла обзора, но требует большего объёма вычислений.
Для того, чтобы использовать этот алгоритм, достаточно выполнить команду:
$ make cnn-detect TEST_IMAGE=”имя_файла”

И хотя алгоритм успешно обнаружил все лица, изображенные на картинке, сам процесс занял более 20 секунд (другие алгоритмы потратили менее секунды). Так что без графического процессора использовать этот алгоритм не стоит.
А вот алгоритм HOG лишен этих недостатков. Данный алгоритм основан на подсчете количества направлений градиента в локальных областях изображения. HOG использует разделение изображения на маленькие связные области, именуемые ячейками, и рассчитывает для каждой ячейки гистограммы направлений градиентов или направлений краёв для пикселей, находящихся внутри ячейки. Комбинация этих гистограмм и является дескриптором искомой области.
Запустить HOG можно командой:
$ make hog-detect TEST_IMAGE=”имя_файла”

Все лица на изображении также распознаны верно, однако здесь все было выполнено менее чем за секунду.
Заключение
Мы познакомились с некоторыми примерами реализации алгоритмов распознавания на Python. В целом, представленные инструменты можно без особых проблем использовать в собственных проектах для распознавания лиц.
Пользуясь случаем, напоминаю об открытых уроках по машинному обучению, которые пройдут в Otus в марте:
3 марта. Основы A/B тестирования для выбора ML модели.
Познакомитесь с оценкой качества ML-моделей при помощи проведения A/B теста, а также научитесь планировать A/B тест и делать выводы о его результатах. Записаться17 марта. Популярные методы ансамблирования, Бэггинг и Градиентный бустинг
Разберем общие принципы ансамблирования и поговорим про такие методы, как Бэггинг и Градиентный бустинг, которые в конце занятия применим на практике. Записаться