OpenCV и обработка изображений

в 7:32, , рубрики: C, c++, opencv, python, Блог компании Издательский дом «Питер», книги, Программирование

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

OpenCV и обработка изображений - 1

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

В этой статье будет рассказано, как сгенерировать усредненное изображение лица при помощи библиотеки OpenCV (C++ / Python).

OpenCV и обработка изображений - 2

Рис. 1

Женщина, изображенная на рис. 1, большинству читателей покажется симпатичной. Но вы можете угадать ее национальность? А почему у нее такая ровная кожа? Правильно – этой женщины не существует. Но и нельзя сказать, что это полностью виртуальное изображение. Это усредненный портрет всех сотрудниц моей компании Sight Commerce Inc. по состоянию примерно на 2011 год. Ее национальность сложно определить, так как у нас работают девушки с европейскими, латиноамериканскими, восточноазиатскими и индийскими корнями!

История усреднения лиц просто увлекательна.

Все началось с исследований Френсиса Гальтона (кузена Чарльза Дарвина), который еще в 1878 году изобрел новый фотографический прием: научился комбинировать лица и составлять первые фотороботы. Он полагал, что, комбинируя лица преступников, можно смоделировать «прототипическое» лицо уголовника и впоследствии распознавать потенциальных преступников по чертам лиц. Оказалось, что эта гипотеза ошибочна: рассмотрев чью-либо фотографию, невозможно определить его склонность к преступлениям.

Однако, Гальтон заметил, что усредненное лицо всегда выглядит привлекательнее всех «составляющих» его лиц. В одном поразительном эксперименте исследователи «сложили» лица всех 22 финалисток конкурса «Мисс Германия — 2002». Опрошенные оценили получившийся портрет выше, чем любую из конкурсанток, даже выше «мисс Берлин», которая тогда оказалась победительницей. Уф! Оказывается, Джессика Альба такая хорошенькая именно потому, что ее лицо близко к среднему.

Можно ли приравнять «среднее» к «посредственному»? Почему усредненное лицо кажется нам привлекательным? Согласно эволюционной гипотезе под названием «койнофилия», особи в активном репродуктивном возрасте ищут партнеров с усредненными чертами, поскольку отклонения от среднего могут свидетельствовать о вредных мутациях. Кроме того, среднее лицо симметрично, поскольку вариации в левой и правой части лица взаимно сглаживаются.
Как сгенерировать усредненное лицо в OpenCV?

OpenCV и обработка изображений - 3

Рис. 2: Усредненное лицо президентов США от Картера до Обамы

Код и изображения к статье можно скачать здесь.

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

Этап 1: Обнаружение черт лица

OpenCV и обработка изображений - 4

Рис. 3: Пример обнаружения черт лица

Для каждого портрета мы рассчитываем 68 «контрольных точек» при помощи библиотеки dlib. О том, как установить и использовать dlib, я подробно рассказываю в другом посте Facial Feature Detection. На портрете Обамы расставлено 68 контрольных точек.

Этап 2: Координация преобразования

На входе размер изображений лиц может сильно отличаться. Поэтому нам придется их нормализовать и привести к одной системе отсчета. Для этого мы деформируем все изображения лиц до размера 600×600, чтобы левый угол левого глаза находился в точке с координатами (180, 200), а правый угол правого глаза – в точке (420, 200). Давайте назовем эту систему отсчета «конечной координатной системой», а координаты исходных изображений – «начальной координатной системой».

Как я выбрал вышеуказанные точки? Я хотел гарантировать, что эти точки будут расположены на одной горизонтальной линии, и эта линия будет пролегать примерно в трети пути от верхнего до нижнего края картинки. Итак, я добивался, чтобы кончики глазниц находились в точках с координатами ( 0.3 x ширина, высота / 3 ) и ( 0.7 x ширина, высота / 3 ).

Нам также известно, где расположены уголки глаз на исходных изображениях – соответственно, в контрольных точках 36 и 45. Затем мы можем вычислить преобразование подобия (вращение, перенос, масштабирование) и перевести точки из начальной координатной системы в конечную.

OpenCV и обработка изображений - 5

Рис. 4: Преобразование подобия используется для превращения исходного изображения размером 3000×2300 в конечное размером 600×600.

Что такое преобразование подобия? Преобразование подобия – это матрица размером 2×3, позволяющая изменять расположение точек (x, y) или целого изображения. Два первых столбца этой матрицы кодируют вращение и масштабирование, а последний — перенос (т.e. смещение). Допустим, вы преобразуете (перемещаете) четыре угла квадрата таким образом, что квадрат масштабируется в направлении x и y в sx и sy раз соответственно. В то же время он поворачивается на угол θ и переносится (перемещается) на tx и ty в направлениях x и y. Преобразование подобия при этом можно записать так:

OpenCV и обработка изображений - 6

Исходя из точки (x, y), вышеописанное преобразование подобия переносит эту точку в (xt, yt) в соответствии со следующим уравнением:

OpenCV и обработка изображений - 7

Преобразование подобия можно выполнить при помощи estimateRigidTransform

// C++
// inPts и outPts – это векторы, состоящие из точек 
// Последний параметр означает, что нас не интересует ни преобразование подобия, 
// ни полное аффинное преобразование
 
cv::estimateRigidTransform(inPts, outPts, false);

# Python 
 
# inPts и outPts - это массивы кортежей из библиотеки numpy
# Последний параметр означает, что нас не интересует ни преобразование подобия, 
# ни полное аффинное преобразование
 
cv2.estimateRigidTransform(inPts, outPts, False);

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

Вычислив преобразование подобия, можно с его помощью превратить исходное изображение и его контрольные точки в конечные координаты. Изображение преобразуется при помощи warpAffine, а точки – при помощи transform.

Этап 3: Выравнивание лица

OpenCV и обработка изображений - 8

Рис. 5: Результат упрощенного усреднения лица

На предыдущем этапе мы смогли преобразовать все изображения и контрольные точки в координаты конечного изображения. Теперь все изображения у нас одного размера, уголки глаз выровнены. Возможно, было бы соблазнительно попытаться получить усредненное изображение, взяв средние пиксельные значения этих выровненных изображений. Однако в таком случае у вас получилась такая картинка, как на рис. 5. Да, глаза выровнены, а все остальные черты лица расположены как попало.

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

Этот процесс подробнее описан в моем посте Face Morphing, а в общих чертах – ниже.

Вычисляем средние лицевые точки

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

Вычисление триангуляции Делоне

OpenCV и обработка изображений - 9

Рис. 6: Вычисление триангуляции Делоне для усредненных контрольных точек.

На предыдущем этапе мы получили положения контрольных точек для усредненного лица в конечных координатах. Можно использовать эти 68 точек (показаны синим цветом на рис. 6) и 8 точек на границе конечного изображения (показаны зеленым) для расчета триангуляции Делоне (показана красным). Подробнее триангуляция Делоне описана здесь.

Триангуляция Делоне позволяет разбить изображение на треугольники. В результате такой триангуляции получаем список треугольников, представленных в виде массива из индексов 76 точек (68 точек на лице + 8 граничных точек). В примере триангуляции, показанном ниже, заметно, что контрольные точки 62, 68 и 60 образуют треугольник, 32, 50 и 49 – другой треугольник и т.д.

Деформация треугольников

Пример триангуляции

[
62 68 60
32 50 49
15 16 72
9 8 58
53 35 36
…  ]

На предыдущем этапе мы вычислили среднее расположение контрольных точек на лице и, опираясь на эти данные, выполнили триангуляцию Делоне, чтобы поделить изображение на треугольники. На рис. 7 видим треугольники Делоне, наложенные на преобразованное исходное изображение, а на том изображении, что находится в середине, показана триангуляция усредненных контрольных точек. Обратите внимание: треугольник 1 на изображении слева соответствует треугольнику 1 на среднем изображении. Зная три вершины треугольника 1, расположенного на левом изображении и соответствующие им три вершины треугольника со среднего изображения, можно рассчитать аффинное преобразование. Повторив эту процедуру для каждого из треугольников с левого изображения, получаем правое изображение. Итак, правое изображение — результат деформации левого до состояния усредненного лица.

OpenCV и обработка изображений - 10

Рис. 7: Деформация изображения на базе триангуляции Делоне

Этап 4: Усреднение лица

Применив манипуляции из предыдущего этапа ко всем исходным изображениям, получаем конечные изображения, деформированные именно так, чтобы результат совпадал с усредненными конечными точками. Чтобы вычислить усредненное изображение, можно просто сложить значения интенсивности пикселов всех деформированных изображений и разделить эту сумму на количество изображений. На рис. 2 показан результат такого усреднения. Он выглядит гораздо лучше, чем то «среднее», что было на рис. 5.
Как по-вашему выглядит «средний» президент США? По-моему — отечески и мило.

Результаты усреднения лица

OpenCV и обработка изображений - 11

Рис. 8: Усредненное лицо Марка Цукерберга, Ларри Пейджа, Илона Маска и Джеффа Безоса

OpenCV и обработка изображений - 12

Рис. 9: Усредненное лицо Бри Ларсон, Джулианны Мур, Кейт Бланшетт и Дженнифер Лоуренс

Как выглядит усредненный ведущий предприниматель-технарь? На рис. 8 показано усредненное лицо Марка Цукерберга, Ларри Пейджа, Илона Маска и Джеффа Безоса. Не могу сказать об этом «среднем предпринимателе» ничего особенного кроме того, что у него все-таки просматривается шевелюра (несмотря на отрицательный вклад Джеффа Безоса).

Как выглядит усредненная оскароносная актриса? На рис. 9 показано усредненное лицо Бри Ларсон, Джулианны Мур, Кейт Бланшетт и Дженнифер Лоуренс. Итак, средняя кинозвезда очень симпатичная. И зубы у нее получше, чем у успешного предпринимателя. Ничего удивительного.

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

OpenCV и обработка изображений - 13

Рис. 10: Симметричный президент Обама (в центре) полученный усреднением его фотографии (слева) с его же зеркальным отражением (справа).

Автор: Издательский дом «Питер»

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js