Если вы не любите читать

Добро пожаловать, все программисты-миллениалы, которые, возможно, открыли эту статью, увидев слова «Snapchat» и «глубокое обучение». Клянусь богом, эти два слова привлекают вас, ребята, как мотылек к пламени. Кого я обманываю, я тоже стал его жертвой, поэтому часами работал над этим проектом.

В этой статье, если вы хотите так ее назвать, я расскажу о процессе и немного теории, лежащей в основе проекта, в названии. Полное раскрытие, даже мое использование термина «Snapchat» в названии могло быть немного кликабельным, потому что, хотя этот проект работает по тому же принципу (использование ключевых точек лица для сопоставления объектов с лицом), он даже не близок к Snapchat. реализация с точки зрения сложности и точности. Разобравшись с этим, позвольте мне начать с представления набора данных, который я использовал.

Набор данных

Я использовал следующий набор данных: https://www.kaggle.com/c/facial-keypoints-detection, предоставленный Dr. Йошуа Бенжио Монреальского университета.

Каждая предсказанная ключевая точка определяется парой (x, y) действительных значений в пространстве индексов пикселей. Есть 15 ключевых точек, которые представляют различные элементы лица. Входное изображение задается в последнем поле файлов данных и состоит из списка пикселей (упорядоченных по строкам) в виде целых чисел в (0,255). Изображения 96x96 пикселей.

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

Шаг 1. Предварительная обработка данных и другие махинации

В приведенном выше наборе данных есть два файла, которые нам нужно обработать - training.csv и test.csv. Учебный файл состоит из 31 столбца: 30 столбцов для координат ключевой точки и последний столбец, содержащий данные изображения в строковом формате. Он содержит 7049 образцов, однако многие из этих примеров имеют значения NaN для некоторых ключевых моментов, что усложняет нам задачу. Поэтому мы будем рассматривать только образцы без каких-либо значений NaN. Вот код, который делает именно это: (Следующий код также нормализует данные изображения и ключевых точек, что является очень распространенным этапом предварительной обработки данных)

Все хорошо и хорошо? Не на самом деле нет. Похоже, что было всего 2140 образцов, которые не содержали значений NaN. Это намного меньше образцов для обучения обобщенной и точной модели. Итак, чтобы создать больше данных, нам нужно увеличить наши текущие данные.

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

Шаг 2: Архитектура модели и обучение

Теперь давайте перейдем к разделу проекта «Глубокое обучение». Мы стремимся предсказать значения координат для каждой ключевой точки невидимого лица, следовательно, это проблема регрессии. Поскольку мы работаем с изображениями, сверточная нейронная сеть - довольно очевидный выбор для извлечения функций. Эти извлеченные функции затем передаются в полностью подключенную нейронную сеть, которая выводит координаты. Последний плотный слой должен иметь 30 нейронов, потому что нам нужно 30 значений (15 пар координат (x, y)).

  • Активация «ReLu» используется после каждого сверточного и плотного слоя, за исключением последнего плотного слоя, поскольку это значения координат, которые нам нужны в качестве выходных.
  • Регуляризация выпадения используется для предотвращения переобучения
  • Максимальное объединение добавлено для уменьшения размерности

Модель смогла достичь минимальных потерь ~ 0,0113 и точности ~ 80%, что я считаю достаточно приличным. Вот несколько результатов работы модели на тестовой выборке:

Мне также нужно было проверить производительность модели на изображении с моей веб-камеры, потому что это то, что модель получит во время реализации фильтра, вот как модель работала на этом изображении моего прекрасного лица:

Шаг 3. Приведите модель в действие

Наша модель заработала, поэтому все, что нам нужно сделать, это использовать OpenCV для выполнения следующих действий:

  1. Получение кадров изображений с веб-камеры
  2. Обнаружение области лица в каждом кадре изображения, потому что другие части изображения бесполезны для модели (я использовал Каскад Хаара на передней части лица, чтобы вырезать область лица)
  3. Предварительно обработайте эту обрезанную область: - преобразованием в оттенки серого, нормализацией и изменением формы.
  4. Передайте предварительно обработанное изображение в качестве входных данных в модель.
  5. Получите прогнозы для ключевых точек и используйте их для размещения различных фильтров на лице.

Когда я начинал тестирование, я не имел в виду никаких конкретных фильтров. Идея проекта пришла мне в голову 22 декабря 2018, и, будучи большим фанатом Рождества, как и любой другой нормальный человек, я решил использовать следующие фильтры:

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

  • Фильтр очков. Для масштабирования используется расстояние между ключевой точкой для левого глаза и левой точки и ключевой точкой для правого глаза. Ключевые точки бровей и левого глаза-левого глаза используются для позиционирования очков.
  • Фильтр бороды. Расстояние между ключевой точкой левой губы и ключевой точкой правой губы используется для масштабирования. Ключевые точки верхней губы и левой губы используются для позиционирования бороды.
  • Фильтр шляпы. Ширина лица используется для масштабирования. Ключевые точки надбровной дуги и ключевые точки для левого глаза-левого глаза используются для позиционирования шляпы.

Код, который выполняет все вышеперечисленное, выглядит следующим образом:

Результат

Выше вы можете увидеть окончательный результат проекта, который содержит видео в реальном времени с фильтрами на моем лице и другое видео в реальном времени с нанесенными на график ключевыми точками.

Ограничения проекта

Хотя проект работает довольно хорошо, я обнаружил несколько недостатков, из-за которых он немного не идеален:

  • Не самая точная модель. Хотя, на мой взгляд, 80% - это неплохо, но еще есть над чем поработать.
  • Эта текущая реализация работает только для выбранного набора фильтров, потому что мне пришлось вручную настроить для более точного позиционирования и масштабирования.
  • Процесс применения фильтра к изображению довольно неэффективен с вычислительной точки зрения, потому что для наложения изображения фильтра .png на изображение веб-камеры на основе альфа-канала мне приходилось применять фильтр попиксельно везде, где альфа не было равно 0 Это иногда приводит к сбою программы, когда она обнаруживает более одного лица на изображении.

Полный код проекта находится на моем Github: https://github.com/agrawal-rohit/Santa-filter-facial-keypoint-regression

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

Чао!