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

OpenPose, разработанный исследователями из Университета Карнеги-Меллона, можно считать передовым подходом для оценки позы человека в реальном времени. Кодовая база находится в открытом доступе на github и очень хорошо документирована. Openpose изначально написан на C ++ и Caffe.

На протяжении всей статьи я также могу ссылаться на некоторый код отсюда, точную реализацию OpenPose с помощью Tensorflow. Используйте эту статью в качестве отправной точки, а потом прочтите весь документ, так как я упустил некоторые конкретные детали из статьи, чтобы сэкономить место.

Эта статья разделена на три части. В первой части будет проанализирована общая настройка OpenPose; основная архитектура нейронной сети и общие обозначения, используемые в статье. Во второй части будут подробно описаны карты достоверности и карты сродства. В третьей части статьи мы обсудим, как в конечном итоге правильно собираются ключевые точки из выходных данных нейронной сети, рассматривая проблему как задачу сопоставления графов.

Прежде чем мы углубимся в подробности OpenPose, стоит отметить, что существует две версии статьи: это и это. Первая оригинальная статья была отправлена ​​24 ноября 2016 года, а самая последняя - 18 декабря 2018 года. Есть пара незначительных отличий, таких как архитектура нейронной сети и некоторые аспекты постобработки, что приводит к повышению скорости и точности. Однако общая идея и общий конвейер остались прежними. Более подробную информацию о различиях вы можете найти в 1-м разделе последней статьи здесь. В этой статье мы рассмотрим исходную версию документа, поскольку на момент написания этой статьи в большинстве реализаций на github все еще используются шаги, описанные в первой статье.

Общий трубопровод

Конвейер от OpenPose на самом деле довольно прост и понятен.

Сначала входное изображение RGB (рис. 1a) подается в качестве входных данных в «двухветвевой многоступенчатый» CNN. Две ветви означают, что CNN производит два разных вывода. Многоступенчатость просто означает, что сеть накладывается одна на другую на каждом этапе. (Этот шаг аналогичен простому увеличению глубины нейронной сети для получения более точных результатов на последних этапах.)

Две ветви: верхняя ветвь, показанная бежевым цветом, предсказывает карты достоверности (рис. 1b) расположения различных частей тела, таких как правый глаз, левый глаз, правый локоть и другие. Нижняя ветвь, показанная синим цветом, предсказывает поля сродства (рис. 1c), которые представляют степень связи между различными частями тела.

Многоэтапный. На первом этапе (левая половина рис. 2) сеть создает начальный набор карт достоверности обнаружения S и набор частичных полей сродства L. Затем на каждом последующем этапе (правая половина рис. 2) прогнозы из обеих ветвей на предыдущем этапе вместе с характеристиками исходного изображения F, объединяются (обозначены знаком + на рис. 2) и используются для получения более точных прогнозов. В реализации OpenPose заключительный этап t выбран равным 6.

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

Наконец, карты достоверности и поля сродства обрабатываются методом жадного вывода (рис. 1d) для вывода двухмерных ключевых точек для всех людей на изображении (рис. 1e).

Карты уверенности

Возвращаясь к рис. 2, верхняя ветвь нейронной сети создает набор карт достоверности обнаружения S. Математически это определяется следующим образом.

J, общее количество частей тела, зависит от набора данных, с которым обучается OpenPose. Для набора данных COCO J = 19, поскольку существует 18 различных ключевых точек тела + 1 фон. На рисунке ниже показаны различные части тела с назначенным им идентификатором для набора данных COCO.

Чтобы лучше понять, что представляет собой набор S, рассмотрим этот пример. Для модели, обученной с помощью набора данных COCO, набор S будет содержать элементы S1, S2, S3,…, S19. В этом примере предположим, что элемент S1 соответствует карте достоверности для идентификатора ключевой точки 0 (на рис. 5), который относится к носу. Тогда карта достоверности может выглядеть следующим образом.

На рис. 6 мы предполагаем, что полное изображение имеет ширину и высоту 5, в результате чего получается карта достоверности 5 X 5. В этом примере на картинке только одно лицо. Следовательно, для карты достоверности S1 (прогнозирует достоверность обнаружения носа) мы видим только область высокой достоверности, 0,9, в области, где есть нос.

Карты поля сходства деталей (PAF)

Возвращаясь к рис. 2, нижняя ветвь нейронной сети создает набор карт поля сродства частей L. Математически это определяется следующим образом.

C, общее количество конечностей, зависит от набора данных, с которым обучается OpenPose. В документе пары частей называются конечностями для ясности, несмотря на то, что некоторые пары частей тела не являются конечностями человека. Для набора данных COCO C = 19. На рисунке ниже показаны различные пары деталей.

Вы можете представить, что каждый элемент в наборе L представляет собой карту размером w x h, где каждая ячейка содержит 2d вектор, представляющий направление парных элементов. Например, на рис. 1c пара частей тела состоит из правого плеча и правого локтя. Затем на диаграмме показан вектор направления, который указывает от правого плеча к правому локтю.

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

Детали нейронной сети

Изображение сначала анализируется предварительно обученной сверточной нейронной сетью, такой как первые 10 слоев VGG-19, для создания набора карт характеристик F. Этот выбор экстрактора признаков для создания F не ограничивается VGG-19. Существуют другие варианты OpenPose, которые используют Mobilenet или Resnet для извлечения функций изображения перед передачей их остальной части нейронной сети, показанной на рис. 2.

Этап 1: сеть создает набор карт достоверности обнаружения S и набор полей сродства частей L. Символ 𝛒 используется как функциональная переменная, которая представляет CNN с входом F для создания выходной карты S. Символ 𝛟 используется как функциональная переменная, которая представляет CNN с входом F для создания выходной карты L. Аннотация «1» в верхней части каждого символа означает вывод на первом этапе.

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

В документе OpenPose t идет от 2 до 6. Запятая на приведенном выше рисунке обозначает конкатенацию между картами.

Функции потерь: чтобы сеть научилась генерировать лучшие наборы S и L, авторы применяют две функции потерь в конец каждого этапа, по одному на каждой ветви соответственно. В документе используются стандартные потери L2 между оценочными прогнозами и наземными картами и полями. (Позже мы также увидим, как авторы придумали способ создания основных карт истинности для каждого S и L). Более того, авторы добавили некоторый вес к функциям потерь, чтобы решить практическую проблему, заключающуюся в том, что некоторые наборы данных не полностью маркируют всех людей. Функции потерь на конкретном этапе t задаются следующим образом.

  1. Обозначение p представляет местоположение одного пикселя в изображении w x h.
  2. Обозначение * рядом с наборами S и L означает, что это истинная правда.
  3. Результатом S (p) является одномерный вектор, который состоит из оценки достоверности для этой конкретной части тела j в местоположении изображения p.
  4. Результатом L (p) является двумерный вектор, который состоит из вектора направления для этой конкретной конечности c в местоположении изображения p.
  5. В документе OpenPose, J, общее количество частей тела равно 19. Кроме того, C, общее количество «конечностей» или соединений тела с телом равно 19.
  6. W (p) представляет функцию взвешивания, как упоминалось ранее. W (p) = 0, когда аннотация отсутствует в месте изображения p. Маска используется, чтобы избежать наказания за истинно положительные прогнозы во время обучения.

Функция общих потерь: Наконец, объединив две функции потерь, мы пришли к общей цели.

Реализация нейронной сети (в Caffe)

Авторы OpenPose используют Caffe для реализации нейронной сети. Не волнуйтесь, если вы не знакомы с Caffe. Как и многие другие фреймворки глубокого обучения, Caffe очень интуитивно понятен и прост для понимания. Модели кафе определены в файлах .prototxt. Ниже представлена ​​усеченная версия модели нейронной сети, определенной с помощью Caffe. Полный файл модели занимает много места, поэтому я решил показать только первые несколько строк. Вы можете найти здесь для полного определения модели.

Чтобы лучше визуализировать архитектуру нейронной сети, мы используем инструмент сетевой визуализации, такой как https://ethereon.github.io/netscope/quickstart.html, где он преобразует тексты в некоторую визуализацию, которая легче для понимания. Я рекомендую вам попробовать его самостоятельно, так как он обладает некоторой интерактивностью, где вы можете навести курсор, и он покажет вам более подробную информацию о каждом модуле.

Здесь следует отметить важный момент: вывод модуля «relu4_4_CPM» представляет собой набор функций изображения F, описанных в документе (Рис. 2). Этот набор функций изображения F объединяется вместе с прогнозами из обеих ветвей, показанных на рис. 2, для получения более точных прогнозов на более поздних этапах.

Этап 1

Как показано на рис. 11, вы можете видеть, что выходные данные модуля «relu4_4_CPM» передаются в два модуля: «conv5_1_CPM_L1» и «conv5_1_CPM_L2 ». Первый модуль соответствует ветви BOTTOM (прогнозирование набора векторов PAF) на рис. 2, а второй модуль соответствует ветви TOP. (прогнозирование набора векторов достоверности) на рис. 2. Выходное измерение «conv5_5_CPM_L2» равно (wxhx 19), где 19 соответствует 19 различным ключевым точкам в наборе данных COCO. . Размер вывода «conv5_5_CPM_L1» равен (Ш x В x 38), где 38 = 19 * 2 соответствует 19 различным «конечностям», определенным в наборе данных COCO. И умножается на 2, поскольку каждая ячейка на карте каждой конечности представляет собой вектор, который имеет значения x и y.

Этап t

Как показано на рис. 12, важно отметить, что этап конкатенации требует трех входных данных. Это F и результат первого этапа S и L. Затем он снова подается в две разные ветви. Этот процесс повторяется до t = 6, после чего возвращается наиболее точные значения.

Затем конечные результаты объединяются и возвращаются для «жадного» сопоставления, обсуждаемого в следующих нескольких частях статьи.