Оцените положение тела используя глубокое обучение

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

Цель оценки положения тела состоит в том, чтобы идентифицировать местоположение людей в изображении и ориентацию их частей тела. Когда в сцене присутствует несколько людей, оценка положения может быть более трудной из-за окклюзии, контакта с телом и близости аналогичных частей тела.

Существует две стратегии оценки положения тела. Стратегия сверху вниз сначала идентифицирует отдельных людей, использующих обнаружение объектов, а затем оценивает положение каждого человека. Стратегия снизу вверх сначала идентифицирует части тела в изображении, таком как носы и левые локти, а затем собирает индивидуумов на основе вероятных пар частей тела. Стратегия снизу вверх более устойчива к окклюзии и контакту тела, но стратегия более трудна для реализации. OpenPose - это многоличный алгоритм оценки положения человека, который использует стратегию снизу вверх [1].

Чтобы идентифицировать части тела в изображении, OpenPose использует предварительно обученную нейронную сеть, которая предсказывает тепловые карты и поля сродства частей (PAFs) для частей тела в вход изображении [2]. Каждая тепловая карта показывает вероятность того, что конкретный тип части тела расположен на каждом пикселе изображения. PAF являются векторными полями, которые указывают, соединены ли две части тела. Для каждого определенного типа сопряжения частей тела, такого как шейка с левым плечом, существует два PAF, которые показывают 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™ Converter для ONNX Model Format.

Если Deep Learning Toolbox Converter™ for ONNX Model Format не установлен, то функция предоставляет ссылку на необходимый пакет поддержки в Add-On Explorer. Чтобы установить пакет поддержки, щелкните ссылку и выберите Установить. Если пакет поддержки установлен, то 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);

Предсказание тепловых карт и PAF тестового изображения

Чтение и отображение тестового изображения.

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");

Предсказать тепловые карты, которые выводятся из 2-D сверточного слоя с именем 'узел _ 147'.

heatmaps = predict(net,netInput,"Outputs","node_147");

Получите числовые данные тепловой карты, хранящиеся в dlarray. Данные имеют 19 каналов. Каждый канал соответствует тепловой карте для уникальной части тела с одной дополнительной тепловой картой для фона.

heatmaps = extractdata(heatmaps);

Отобразите тепловые карты в монтаже, переведя данные в область значений [0, 1], ожидаемый от изображений типа данных single. Сцена насчитывает шесть человек, а в каждой тепловой карте - шесть ярких пятен.

montage(rescale(heatmaps),"BackgroundColor","b","BorderSize",3)

Чтобы визуализировать соответствие ярких пятен телам, отобразите первую тепловую карту в фальсколоре над тестовым изображением.

idx = 1;
hmap = heatmaps(:,:,idx);
hmap = imresize(hmap,size(im,[1 2]));
imshowpair(hmap,im);

Алгоритм OpenPose не использует фоновую тепловую карту для определения местоположения частей тела. Удалите фоновую тепловую карту.

heatmaps = heatmaps(:,:,1:end-1);

Предсказать PAFs, которые выводятся из 2-D сверточного слоя с именем 'узел _ 150'.

pafs = predict(net,netInput,"Outputs","node_150");

Получите числовые данные PAF, хранящиеся в dlarray. Данные имеют 38 каналов. Существует два канала для каждого типа сопряжения частей тела, которые представляют x - и y-компонент векторного поля.

pafs = extractdata(pafs);

Отображение PAF в монтаже, преобразование данных в область значений [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)

Чтобы визуализировать соответствие PAF с телами, отобразите x - и y-компонент пары частей тела первого типа в фальсеколе над тестовым изображением.

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);

Идентифицируйте положения тепловых карт и PAF

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

Получите параметры алгоритма OpenPose с помощью getBodyPoseParameters вспомогательная функция. Функция присоединена к примеру как вспомогательный файл. Функция возвращает struct с такими параметрами, как количество частей тела и соединений между типами деталей тела, которые необходимо учитывать. Параметры также включают пороги, которые можно настроить, чтобы улучшить эффективность алгоритма.

params = getBodyPoseParameters;

Идентифицируйте отдельных людей и их положения при помощи getBodyPoses вспомогательная функция. Эта функция присоединена к примеру как вспомогательный файл. Функция helper выполняет все шаги постобработки для оценки положения:

  1. Определите точные местоположения частей тела из тепловых карт с помощью немаксимального подавления.

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

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

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

  5. Зная, какие части тела соединены, соберите части тела в отдельные положения для каждого отдельного человека.

Функция helper возвращает матрицу 3-D. Первая размерность представляет количество идентифицированных людей на изображении. Это второе измерение представляет количество типов деталей тела. Третья размерность указывает координаты x и y для каждой части тела каждого человека. Если часть тела не обнаружена в изображении, то координаты для этой части являются [NaN NaN].

poses = getBodyPoses(heatmaps,pafs,params);

Отобразите положения тела с помощью renderBodyPoses вспомогательная функция. Эта функция присоединена к примеру как вспомогательный файл.

renderBodyPoses(im,poses,size(heatmaps,1),size(heatmaps,2),params);

Ссылки

[1] Cao, Zhe, Gines Idalgo, Tomas Simon, Shih-En Wei, and Yaser Sheikh. OpenPose: оценка положения многопользовательской 2D в реальном времени с использованием полей сходства деталей. ArXiv:1812.08008 [Cs], 30 мая 2019 года. https://arxiv.org/abs/1812.08008.

[2] Осокин, Даниил. Оценка положения 2D нескольких лиц на центральном процессоре в реальном времени: облегченный OpenPose. ArXiv:1811.12004 [Cs], 29 ноября 2018 года. https://arxiv.org/abs/1811.12004.

См. также

(Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox)

Для просмотра документации необходимо авторизоваться на сайте