Автор: Андрей Сорокин, Senior Developer DataArt

В конце прошлого года мы завершили R&D-проект, посвященный методам машинного зрения в обработке изображений. В результате мы создали ряд усредненных портретов IT-специалистов, работающих с разными технологиями. В этой статье я расскажу об изображениях «типичных» Java и .NET-программистов, подходящих для этого фреймворках и оптимизации процесса.

Тема машинного зрения меня интересует еще с аспирантуры — моя кандидатская была посвящена распознаванию рукописных текстов. За последние несколько лет произошли существенные изменения в методологии и программном обеспечении для машинного зрения, появились новые инструменты и фреймворки, которые хотелось попробовать. В этом проекте мы не претендовали на изобретение уникального решения — главный вклад мы внесли в оптимизацию обработки изображений.

Идея создать портрет «среднего представителя», конечно, не уникальна. Например, в октябре автор Reddit osmutiar выкладывал на ресурс средние портреты профессиональных бейсболиста, баскетболиста, игрока в гольф и т. д.


На этой картинке лица, созданные osmitar на основе 1800 портретов игроков американской MLB и 500 лучших действующих футболистов мира.

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


На самом деле, портреты на иллюстрации в конце проходили дополнительную художественную обработку.

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


Полученный в итоге портрет «среднего» коллеги-мужчины из DataArt.

Всего мы проанализировали 1541 мужское и 512 женских лиц, взятых из нашей внутренней системы учета рабочего времени. Первыми проблемами, с которыми мы столкнулись, были маленький размер фотографий — всего 80 на 120 точек — и отсутствие стандарта для съемки. Поворот и наклон головы на фото у всех были разными, изначально программа обнаруживала лица только на 927 мужских и 85 женских фотопортретов. Поэтому первым делом нужно было нормализовать положение лиц.


Фотографии до и после выравнивания наклона головы.

После увеличения размера и интерполяции точек на изображении заработал детектор, основанный на методе гистограмм ориентированных градиентов (Histogram of Oriented Gradients — HOG).

Для слияния предварительно обработанных нашим алгоритмом лиц мы использовался метод, предложенный Сатьей Малликом, исследователем индийского происхождения, который работает в Калифорнийском университете в Сан-Диего. Мы выделили 68 ключевых точек на каждом лице в выборке: координаты уголков глаз, бровей, губ, носа. Затем произвели триангуляцию каждого лица по этим ключевым точкам, то есть разделили его на треугольники.


Так выглядят схемы лиц после триангуляции.


Так выглядит реальный портрет после трансформации в соответствии с усредненной моделью лица.

И, наконец, для всех лиц в выборке усреднили цвета пикселей внутри соответствующих треугольников.

Дополнительно было интересно посмотреть на кластеризацию исходных изображений. Для выделения групп лиц мы использовали спектральный анализ дескрипторов изображений, с выборкой N главных компонентов. Матрица признаков (MxN), где M — количество образцов, N — количество компонентов векторов признаков, подвергается SVD-разложению. Отбираются наибольшие собственные значения, соответствующие им собственные векторы, а остальные образцы разбиваются по этим топ N кластерам («близким» к центрам кластеров, заданных собственными векторами). Иными словами, отбираются пять самых непохожих друг на друга групп из представленных образцов. Затем из каждой группы выбираются по три изображения. Таким образом, мы получаем контрастное усредненное лицо за счет использования меньшего количества образцов, тем не менее, все кластеры в результирующем изображении представлены. В итоге мы получили ряд типичных портретов, выбранных алгоритмом. Изображения не получились «безликими» или слишком похожими друг на друга. При простом слиянии достаточно большого количества изображений это было бы практически неизбежно.

Результаты



Java Girl Java Boy .NET Girl .NET Boy
Портреты, полученные с применением кластерного анализа (слиянием топ-3 лиц в каждом из пяти кластеров).
Изображения, полученные простым слиянием портретов всех .NET и Java-программистов.


Большая часть манипуляций с изображением (работа с точками изображений, аффинные преобразования и работа с цветом) использует алгоритмы, реализованные во фреймворке opencv. Для выделения ключевых точек лиц, как и самих лиц, на изображении используются фреймворк dlib и предварительно обученная модель оценки положения лица (здесь мы выступили в роли пользователей модели Davis King), например, shape_predictor_68_face_landmarks.dat, обученный на коллекции изображений iBUG 300W. То есть мы просто подаем на вход модели изображение 150 х 150 пикселей и получаем 68 точек на выходе — вектор фиксированной длины.

Заключительную часть Сатья Маллик реализовал на Python, мы же в основном переписали ее на C++. Это позволило увеличить скорость обработки, снизить объем потребляемой памяти и обеспечить целостность решения.

Еще одной проблемой стало большое потребление памяти (> 4Гб) на слиянии уже 300 изображений. Ее мы решили, проанализировав предложенный Малликом код для слияния — все исходные изображения считывались одновременно перед слиянием. Нас это устроить не могло: в нашем случае всего нужно было прочитать 1541 файл. Если бы размеры изображений были чуть больше, не хватило бы и 32 Гб. Эта проблема была решена переписыванием куска кода и инкрементальным слиянием следующего прочитанного изображения. Теперь объем использованной памяти не превышает 100 Мб (хранятся только усредненные координаты «ключевых точек» лиц, одно обрабатываемое изображение и загруженные классификаторы — fHOG и загруженные модели).

Комментарии (11)


  1. AndrewRo
    24.01.2018 23:20

    Портрет тайваньца расплывается меньше всех. Похоже, что все азиаты на одно лицо — не просто стереотип.


    1. erwins22
      25.01.2018 09:36

      Вероятно выбор 68 ключевых точек ориентирован на распознавание лица европиоида?


      1. xFFFF
        25.01.2018 10:26

        Типа у азиатов надо больше точек?)))


        1. erwins22
          25.01.2018 11:59

          допустим на лице мы выделим 1000 точек. И по европиоидному лицу выделим 68 самых важных(практически не меняющимися у одного индивидуума и наиболее сильно различающиеся у разных). Вопрос, будут ли эти же 68 точек самыми важными по монголоидному лицу?


          1. masai
            25.01.2018 14:27

            Эти точки ключевые с точки зрения положения структурных элементов лица, общих для всех: кончик носа, переносица, кончик подбородка, края губ и т. д. Это всё есть у каждого здорового человека независимо от расы.


            1. erwins22
              25.01.2018 18:46

              Как мне говорил один знакомый китаец — русские все на одно лицо.


  1. Dark_Daiver
    24.01.2018 23:34

    предварительно обученная модель нейросети (здесь мы выступили в роли пользователей модели Davis King), например, shape_predictor_68_face_landmarks.dat


    Поправьте меня, но вроде в dlib для поиска facial landmarks не нейросети, а деревья — One Millisecond Face Alignment with an Ensemble of Regression Trees (http://dlib.net/face_landmark_detection.py.html)


    1. DataArt Автор
      25.01.2018 12:53

      Ответ — да, абсолютно верно, использовалась модель на основе random forests для поиска ключевых точек лица. Неточность появилась из-за того, что за рамками статьи была попытка пропустить изображение полученных лиц через нейросеть — https://github.com/davisking/dlib-models/blob/master/dlib_face_recognition_resnet_model_v1.dat.bz2, чтобы в дальнейшем использовать этот вектор-дескриптор для кластеризации лиц (вместо вектора facial landmarks)/ Но в дальнейшем от такой кластеризации отказались — работает медленнее и интерпретировать полученный кластер сложнее — нет прямого соответствия ключевым точкам лица, кроме того результат визуально малоразличим.


      Вот сравнение кластеризации на основе resnet и landmarks.


      1. DataArt Автор
        25.01.2018 14:28

        На всякий случай слева resnet, справа — landmarks.


  1. Z0K
    25.01.2018 16:54

    Java Girl здесь самая лучшая!

    Было бы забавно натравить алгоритм на условную базу каких-нибудь резюме с HeadHunter и получить усреднённые фотографии девушек на разных позициях. alextheraven, сделайте!


    1. dskozin
      25.01.2018 17:42

      Про Java герлу с языка снял...