В этом примере показано, как оценить положение тела одного или нескольких людей, использующих алгоритм OpenPose и предварительно обученную сеть.
Цель оценки положения тела состоит в том, чтобы идентифицировать местоположение людей в изображении и ориентации их частей тела. Когда несколько человек присутствуют в сцене, оценка положения может больше затруднить из-за поглощения газов, физического контакта и близости подобных частей тела.
Существует две стратегии к оценке положения тела. Нисходящая стратегия сначала идентифицирует отдельных людей, использующих обнаружение объектов, и затем оценивает положение каждого человека. Восходящая стратегия сначала идентифицирует части тела в изображении, такие как носы и оставленные колена, и затем собирает индивидуумов на основе вероятных соединений частей тела. Восходящая стратегия более устойчива к поглощению газов и физическому контакту, но стратегия больше затрудняет реализацию. OpenPose является человеческим алгоритмом оценки положения для нескольких человек, который использует восходящую стратегию [1].
Чтобы идентифицировать части тела в изображении, OpenPose использует предварительно обученную нейронную сеть, которая предсказывает тепловые карты и поля сродства части (PAFs) для частей тела во входном изображении [2]. Каждая тепловая карта показывает вероятность, что конкретный тип части тела расположен на уровне каждого пикселя в изображении. PAFs являются векторными полями, которые указывают, соединяются ли две части тела. Для каждого заданного типа соединения части тела, такого как шея к левому плечу, существует два PAFs, которые показывают x-и y-компонент векторного поля между экземплярами частей тела.
Чтобы собрать части тела в отдельных людей, алгоритм OpenPose выполняет ряд операций последующей обработки. Первая операция идентифицирует и локализованные части тела с помощью тепловых карт, возвращенных сетью. Последующие операции идентифицируют фактические связи между частями тела, приводящими к отдельным положениям. Для получения дополнительной информации об алгоритме, смотрите, Идентифицируют Положения от Тепловых карт и PAFs.
Импортируйте предварительно обученную сеть из файла ONNX.
dataDir = fullfile(tempdir,'OpenPose'); trainedOpenPoseNet_url = 'https://ssd.mathworks.com/supportfiles/vision/data/human-pose-estimation.zip'; downloadTrainedOpenPoseNet(trainedOpenPoseNet_url,dataDir) unzip(fullfile(dataDir,'human-pose-estimation.zip'),dataDir);
Загрузите и установите Конвертер Deep Learning Toolbox™ для пакета поддержки Формата Модели ONNX.
Если Deep Learning Toolbox, Converter™ для Формата Модели ONNX не установлен, то функция обеспечивает ссылку на необходимый пакет поддержки в Add-On Explorer. Чтобы установить пакет поддержки, щелкните по ссылке, и затем нажмите Install. Если пакет поддержки установлен, то importONNXLayers
функция возвращает LayerGraph
объект.
modelfile = fullfile(dataDir,'human-pose-estimation.onnx'); layers = importONNXLayers(modelfile,"ImportWeights",true);
Удалите неиспользованные выходные слои.
layers = removeLayers(layers,["Output_node_95" "Output_node_98" "Output_node_147" "Output_node_150"]); net = dlnetwork(layers);
Считайте и отобразите тестовое изображение.
im = imread("visionteam.jpg");
imshow(im)
Сеть ожидает данные изображения типа данных single
в области значений [-0.5, 0.5]. Переключите и перемасштабируйте данные к этой области значений.
netInput = im2single(im)-0.5;
Сеть ожидает цветовые каналы в порядке, синем, зеленом, красном. Переключите порядок каналов цвета изображения.
netInput = netInput(:,:,[3 2 1]);
Сохраните данные изображения как dlarray
.
netInput = dlarray(netInput,"SSC");
Предскажите тепловые карты, которые выводятся от 2D сверточного слоя, названного 'node_147'.
heatmaps = predict(net,netInput,"Outputs","node_147");
Получите числовые данные о тепловой карте, хранимые в dlarray
. Данные имеют 19 каналов. Каждый канал соответствует тепловой карте для уникальной части тела с одной дополнительной тепловой картой для фона.
heatmaps = extractdata(heatmaps);
Отобразите тепловые карты в монтаже, перемасштабировав данные к области значений [0, 1] ожидаемый изображений типа данных single
. Сцена имеет шесть человек, и в каждой тепловой карте существует шесть ярких пятен.
montage(rescale(heatmaps),"BackgroundColor","b","BorderSize",3)
Чтобы визуализировать соответствие ярких пятен с телами, отобразите первую тепловую карту в falsecolor по тестовому изображению.
idx = 1; hmap = heatmaps(:,:,idx); hmap = imresize(hmap,size(im,[1 2])); imshowpair(hmap,im);
Алгоритм OpenPose не использует фоновую тепловую карту, чтобы определить местоположение частей тела. Удалите фоновую тепловую карту.
heatmaps = heatmaps(:,:,1:end-1);
Предскажите PAFs, которые выводятся от 2D сверточного слоя, названного 'node_150'.
pafs = predict(net,netInput,"Outputs","node_150");
Получите числовые данные PAF, хранимые в dlarray
. Данные имеют 38 каналов. Существует два канала для каждого типа соединения части тела, которые представляют x-и y-компонент векторного поля.
pafs = extractdata(pafs);
Отобразите PAFs в монтаже, перемасштабировав данные к области значений [0, 1] ожидаемый изображений типа данных single
. Эти два столбца показывают x-и y-компоненты векторного поля, соответственно. Соединения части тела находятся в порядке, определенном params.PAF_INDEX
значение.
Пары частей тела с в основном вертикальной связью имеют большие величины для соединений y-компонента и незначительные значения для соединений x-компонента. Одним примером является правое бедро к связи правого колена, которая появляется во второй строке. Обратите внимание на то, что PAFs зависят от фактических положений в изображении. Изображение с телом в различной ориентации, такой как то, чтобы ложиться, будет не обязательно иметь большую величину y-компонента для правого бедра к связи правого колена.
Пары частей тела с в основном горизонтальной связью имеют большие величины для соединений x-компонента и незначительные значения для соединений y-компонента. Одним примером является шея к связи левого плеча, которая появляется в седьмой строке.
Пары части тела под углом имеют значения и для x-и для y-компонентов векторного поля. Одним примером является шея к левому бедру, которое появляется в первой строке.
montage(rescale(pafs),"Size",[19 2],"BackgroundColor","b","BorderSize",3)
Чтобы визуализировать соответствие PAFs с телами, отобразите x-и y-компонент первого типа пары части тела в falsecolor по тестовому изображению.
idx = 1; impair = horzcat(im,im); pafpair = horzcat(pafs(:,:,2*idx-1),pafs(:,:,2*idx)); pafpair = imresize(pafpair,size(impair,[1 2])); imshowpair(pafpair,impair);
Часть последующей обработки алгоритма идентифицирует отдельные положения людей в изображении с помощью тепловых карт и PAFs, возвращенного нейронной сетью.
Получите параметры алгоритма OpenPose с помощью getBodyPoseParameters
функция помощника. Функция присоединена к примеру как к вспомогательному файлу. Функция возвращает struct параметрами, такими как количество частей тела и связей между типами части тела, чтобы рассмотреть. Параметры также включают пороги, которые можно настроить, чтобы улучшать производительность алгоритма.
params = getBodyPoseParameters;
Идентифицируйте отдельных людей и их положения при помощи getBodyPoses
функция помощника. Эта функция присоединена к примеру как вспомогательный файл. Функция помощника выполняет все шаги последующей обработки для оценки положения:
Обнаружьте точные местоположения части тела от тепловых карт с помощью немаксимального подавления.
Для каждого типа соединения части тела сгенерируйте все возможные пары между обнаруженными частями тела. Например, сгенерируйте все возможные пары между этими шестью шеями и шестью левыми плечами. Результатом является биграф.
Выиграйте пары путем вычисления линейного интеграла прямой линии, соединяющей две обнаруженных части тела через векторное поле PAF. Большой счет указывает на сильную связь между обнаруженными частями тела.
Сортировка возможных пар их баллами и находит допустимые пары. Допустимые пары части тела являются парами, которые соединяют две части тела, которые принадлежат тому же человеку. Как правило, пары с самым большим счетом рассматриваются первыми, потому что они, скорее всего, будут допустимой парой. Однако алгоритм компенсирует поглощение газов и близость с помощью дополнительных ограничений. Например, у того же человека не может быть дублирующихся пар частей тела, и одна часть тела не может принадлежать двум различным людям.
Знание, какие части тела соединяются, собирает части тела в отдельные положения для каждого физического лица.
Функция помощника возвращает 3-D матрицу. Первая размерность представляет количество идентифицированных людей в изображении. Второе измерение представляет количество типов части тела. Третья размерность указывает на x-и y-координаты для каждой части тела каждого человека. Если часть тела не обнаруживается в изображении, то координаты для той части [NaN NaN].
poses = getBodyPoses(heatmaps,pafs,params);
Отобразите положения тела с помощью renderBodyPoses
функция помощника. Эта функция присоединена к примеру как вспомогательный файл.
renderBodyPoses(im,poses,size(heatmaps,1),size(heatmaps,2),params);
[1] Главный администратор, Чжэ, Хинес Идальго, Томас Саймон, Shih En Wei и Ясер Шейх. “OpenPose: 2D Оценка Положения Для нескольких человек В реальном времени Используя Поля Сродства Части”. ArXiv:1812.08008 [Cs], 30 мая 2019. https://arxiv.org/abs/1812.08008.
[2] Osokin, Даниил. “2D Оценка Положения Для нескольких человек в реальном времени на центральном процессоре: Легкий вес OpenPose”. ArXiv:1811.12004 [Cs], 29 ноября 2018. https://arxiv.org/abs/1811.12004.