[recovery mode] DIY Face Averaging
Узнали кого-нибудь? Всех людей выше не существует: это не фотография, а результат работы несложного алгоритма, усредняющего тысячи разных лиц. В этой статье мы поговорим о том, как легко в кратчайшие сроки набросать такой алгоритм и получить интересные результаты.
Итак, однажды весенним субботним вечером у меня возникло желание выделить некоторый базовый набор черт лица для последующей идентификации. Это не было связано с моей работой, просто хобби. Я решил начать с построения усреднённого лица, относительно которого будет проще выбирать отклонения и отслеживать влияние отдельных черт на общее строение лица. Вообще эта задача довольно успешно решается, обычно с применением Image Warp или иных нелинейных преобразований системы координат, которые по большому счёту не всегда можно называть усреднением, но мы пойдём иным путём.
Спешу заверить, в этой статье нет:
- Зубодробительной математики
- Готовых кусков кода
- Оптимальных решений
Т.к. этот проект начался для меня в качестве побочного в ходе решения узкой задачи, большая часть действий здесь выполнена Just For Fun, без оглядки на Best Practices с мыслью о быстрой несложной разработке. Зато здесь есть честное усреднение, без изменения пропорций и формы лица. Я буду использовать в своей работе Matlab, но вы, ежели решите повторить мой опыт, можете выбрать практически любой язык и среду программирования, т.к. здесь не используется каких-то слишком сложных конструкций, которые нельзя было бы написать на чём угодно за день.
Критически важный для всей последующей затеи этап. Нам необходим достаточно большой набор исходных снимков.
На что мы будем обращать внимание при подборе снимков для нашей базы:
- Объём базы. Я часто видел, когда подобную задачу решали на базе с количеством снимков порядка сотни. Этого явно недостаточно для последующей фильтрации базы в соответствии с различными признаками.
- Качество снимков. Для получения детального результата желательно иметь высококачественные снимки (с оглядкой на возможности железа по обработке всего этого дела)
- Освещение. Здесь лишь одно строгое правило: освещение не должно значительно изменяться от снимка к снимку. Также хотелось бы максимально избежать наличия затенённых участков, но даже с ними наш алгоритм будет работать.
- Положение лица на снимке. Было бы идеально иметь маркеры положения для основных черт лица, но, если их нет, без этого тоже можно обойтись.
- Эмоции, головные уборы, модификации тела. Всё это сильно усложнит работу, потому желательно заранее удалить из базы наиболее вопиюще несоответствующие снимки.
По вышеприведённым параметрам мне очень приглянулась база Humanae, освещавшаяся на TED, где я её, собственно, и увидел. Она содержит порядка 3000 высококачественных снимков с вполне равномерным освещением, однородным фоном и достаточно стабильными положением и выражением лица:
Перед началом работы нам следует скачать базу и привести все снимки к одному размеру. Можно использовать и снимки разных размеров, но с т.з. программирования мне было так удобнее. Затем нужно разделить все 3000 изображений на классы. Это будет необходимо для фильтрации исходников и получения усреднённых лиц разных групп. Это самый долгий и муторный этап всей работы.
Я использовал для классификации следующие параметры:
- Пол: Мужской, Женский, Неочевидно.
- Цвет кожи: 0–255. Можно взять из цвета фона.
- Возраст: Дети, Взрослые, Престарелые.
- Субъективная красота: 0, 1 (норма, отсутствуют явные дефекты), 2 (привлекательные).
Мы будем использовать их в качестве фильтров, чтобы получать различные результаты. Можно обойтись совсем без отбора, вы получите некое усреднённое лицо, черты которого будут зависеть от количества представленных в базе людей с теми или иными особенностями. Разделение по половому признаку мы будем производить обязательно, потому как внешне черты мужчин и женщин разнятся больше всего.
Если Вы выбрали ту же базу, что и я, вам может помочь отсев детей (их несколько десятков), чернокожих (порядка нескольких сотен) и людей с явными физическими дефектами, чтобы получить менее смазанный результат. Это не связано с каким-то шовинизмом или политическими заявлениями, просто численность этих групп в базе зачастую слишком низка, а черты слишком отличны от среднестатистических. В любом случае, всегда можно инвертировать фильтр и построить усреднённые лица именно для этих групп, хотя и достаточно неточные.
Рис 1. Пример усреднённого лица по сильно ограниченному набору снимков (темнокожие взрослые)
Теперь, когда мы имеем сформированную базу, пора перейти непосредственно к размышлению о том, как же добиться необходимого результата. Во-первых, я сразу исключу различные готовые библиотеки Pattern Matching, Image Warping, а также любую сложную математику. Мы ведь хотим просто по-быстрому накидать рабочий код и получить удовольствие, не так ли?
Несовершенство наивного метода
Жизнь была бы простой и приятной, если бы можно было просто сложить весь набор фотографий и получить результат. Увы, жестокая реальность отвечает на наши фантазии достаточно посредственным результатом для мужского усреднённого лица. Можно значительно улучшить получаемое наивным методом изображение, если для каждого последующего фото искать наиболее подходящее преобразование системы координат (позицию, масштаб и др). Как это сделать? Можно использовать разные подходы:
- Вышеупомянутые готовые алгоритмы pattern matching. Ищем набор общих точек, строим по ним преобразование. В matlab есть готовые алгоритмы, но мне так и не удалось заставить их хорошо работать на усреднённых лицах, потому использовать этот метод не будем.
- Кросскорреляция. Достаточно простой в использовании метод поиска подходящей позиции, который к тому же прекрасно считается на GPU. В теории он несколько примитивнее, т.к. преобразование не учитывает поворот и масштаб изображения, но вполне достаточен для наших целей. В matlab можно использовать функцию normxcorr2.
Первый проход наивным и корреляционным методами для сравнения:
Рис 2. Сравнение наивного (слева) и корреляционного (справа) методов
Фокусировка и уточнение
Картинка выше всё ещё выглядит достаточно размытой, теперь следует сосредоточиться на выделении основных черт лица. Потому будем искать на снимках и центрировать не всё лицо, а отдельные детали, полученные на предыдущем этапе:
Рис 3. Участки для корреляции
Естественно, желательно как-то отбирать снимки по значению коэффициента корреляции, чтобы не пропускать в результат совсем неподходящие. Я реализовал это просто в виде пороговой функции с автоподстройкой. Скажем, пусть порог t=0.5, перебираем снимки один за другим в случайном порядке. Отбраковываются все новые снимки, корреляция которых меньше 0.5 по данному участку или с текущим результатом. Если снимок не отбракован, порог t вырастает на 0.003, иначе снижается на 0.001. В результате регулируется доля снимков, попадающих в результат. Система самостоятельно уравновешивается на подходящем значении t. Можно было реализовать как-то иначе, здесь алгоритм отбора на вашей совести.
В результате получим набор изображений с разными областями фокуса. Остаётся объединить их в ручном или автоматическом режиме, чтобы получить достаточно точное изображение.
Рис. 4. Постепенное уточнение и фокусировка основных черт лица
Дополнительные черты
К настоящему моменту мы уже имеем достаточно выраженные основные черты и форму лица, но замечаем, что усреднение «съело» все особенности: волосы, текстуру кожи и брови, сделав лицо несколько синтетическим. Исправить это можно, выставив высокий порог, чтобы отбор прошли лишь одно или несколько наиболее похожих лиц. Смешать полученные дополнительные черты с основными можно автоматически, но я это делал вручную. Естественно переносить желательно только те мелкие детали, которые были утеряны.
Рис. 5. Мужское усреднённое лицо, более 500 снимков.
Перед публикацией этой статьи я рассчитывал прогнать первое полученное лицо через FindFace, но тот заглючил, и в итоге это не понадобилось. Я уже знал того человека, которого мне явно напоминал рисунок выше. По завершении с экрана на меня смотрел… я сам. Я понимаю, что усреднённое лицо должно так сочетать черты всех людей, чтобы быть несколько похожим абсолютно на всех, но совпадение было слишком значительным, чтобы его не отметить. Оставалось лишь сделать более или менее похожий в плане ракурса и света снимок, а затем совместить его с результатом для наглядности:
Я посчитал излишним своё фото прямо в статье из соображений минимальной приватности и уместности, потому, пожалуйста, используйте эту текстовую ссылку drive.google.com/file/d/0B3QDURLCBJrBOGpONmJMbTZPanc/view? usp=sharing Спасибо за понимание.
После получения усреднённого лица было несложно найти всевозможные типичные классы для глаз, носов, ртов и наглядно оценить их влияние на форму лица. Для глаз я выделил 35 различных классов, из них в основном женских четырнадцать:
Рис. 6. Четырнадцать видов женских глаз и их влияние на форму лица
Коротенькая иллюстрация работы первого этапа алгоритма:
Также может быть интересно:
- Выбрать снимки с наибольшими отклонениями от среднего и усреднить их. Скорее всего, существуют другие популярные сочетания черт, которые алгоритм упустил при массовом усреднении. На самом деле правый персонаж на КДПВ получен именно таким образом, и я уверен, что он не один такой.
- Искать и усреднять снимки, похожие на определённого реально существующего человека.
- Из полученных классов черт лица найти наиболее популярное сочетание и усреднить. Полученное таким образом лицо может несколько отличаться от приведённых выше.