主要内容

使用深度学习估计身体姿势

这个例子展示了如何使用OpenPose算法和预先训练的网络来估计一个或多个人的身体姿势。

身体姿态估计的目标是识别人在图像中的位置和身体部位的方向。当一个场景中有多人在场时,由于遮挡、身体接触和相似身体部位的接近,姿态估计可能会更加困难。

估计身体姿势有两种策略。自上而下的策略首先使用对象检测识别个人,然后估计每个人的姿势。自下而上的策略首先识别图像中的身体部位,如鼻子和左肘部,然后根据身体部位的可能配对组合个体。自底向上策略对遮挡和身体接触更具鲁棒性,但该策略更难实现。OpenPose是一种使用自底向上策略的多人人体姿势估计算法[1.].

为了识别图像中的身体部位,OpenPose使用预训练神经网络预测输入图像中身体部位的热图和部位亲和场(PAF)[2.].每个热图都显示了特定类型的身体部位位于图像中的每个像素点的概率。paf是指示身体两个部分是否连接的向量场。对于每种定义的身体部位配对类型,例如脖子到左肩,都有两个paf显示身体部位实例之间向量场的x和y分量。

为了将身体部位组装成个体,OpenPose算法执行一系列后处理操作。第一个操作使用网络返回的热图识别并定位身体部位。后续操作识别身体部位之间的实际连接,从而形成个体姿势。有关e算法,参见从热图和paf中识别姿势

导入网络

从ONNX文件导入预训练网络。

dataDir=fullfile(tempdir,“OpenPose”);培训开放网址='https://ssd.mathworks.com/金宝appsupportfiles/vision/data/human-pose-estimation.zip';downloadTrainedOpenPoseNet (trainedOpenPoseNet_url dataDir)解压缩(fullfile (dataDir,'人体姿势估计.zip'), dataDir);

下载并安装深度学习工具箱™ ONNX模型格式支持包的转换器。金宝app

如果ONNX模型格式的深度学习工具箱转换器™没有安装,那么该函数将提供到Add-On Explorer中所需的支持包的链接。金宝app要安装支持包,请单击链接,然后金宝app单击“安装”。如果已安装支持金宝app包,则重要人物函数返回一个分层图对象

modelfile = fullfile (dataDir,“human-pose-estimation.onnx”);层= importONNXLayers (modelfile,“ImportWeights”,对);

删除未使用的输出层。

层= removeLayers(层,“输出节点95”“Output_node_98”“输出_节点_147”“输出节点150”]); net=dlnetwork(层);

预测测试图像的热图和paf

读取并显示测试图像。

im=imread(“visiontam.jpg”);imshow (im)

网络需要数据类型的图像数据仅有一个的在[-0.5,0.5]范围内。将数据移动并重新缩放到此范围。

netInput = im2single (im) -0.5;

网络希望颜色通道的顺序为蓝色、绿色、红色。请切换图像颜色通道的顺序。

netInput=netInput(:,:,[3 2 1]);

将图像数据存储为dlarray

netInput = dlarray (netInput,“SSC”);

预测从名为“node_147”的二维卷积层输出的热图。

热图=预测(净、净输入、,“产出”,“node_147”);

获取存储在中的数字热图数据dlarray. 数据有19个通道。每个通道对应一个独特身体部位的热图,另外一个热图用于背景。

热图=提取数据(热图);

在蒙太奇中显示热图,将数据重新缩放到数据类型图像的预期范围[0,1]仅有一个的. 现场有六个人,每个热图上有六个亮点。

蒙太奇(重缩放(热图),“背景色”,“b”,“BorderSize”3)

要可视化亮点与物体的对应关系,请在测试图像上以假彩色显示第一个热图。

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

OpenPose算法不使用背景热图来确定身体部位的位置。移除背景热图。

热图=热图(::1:end-1);

预测从名为“node_150”的二维卷积层输出的PAF。

netInput拥堵=预测(净,“产出”,“节点_150”);

方法中存储的数字PAF数据dlarray.数据有38个通道。每种类型的身体部位配对都有两个通道,它们表示向量场的x和y分量。

pafs=提取数据(pafs);

以蒙太奇方式显示paf,将数据缩放到数据类型图像的预期范围[0,1]仅有一个的。这两列分别显示向量场的x和y分量。身体部位对的顺序由参数PAF_指数价值

  • 大部分垂直连接的身体部位对y分量对的大小较大,而对x分量对的大小可忽略不计。一个例子是右髋到右膝的连接,显示在第二行。请注意,PAF取决于图像中的实际姿势。具有不同方向身体的图像对于右髋到右膝的连接,离子(如躺下)不一定具有较大的y分量幅值。

  • 以水平连接为主的身体部位对,x分量对的大小较大,y分量对的大小可忽略不计。一个例子是颈部到左肩部的连接,显示在第七行。

  • 成一定角度的身体部位对具有向量场的x和y分量的值。例如,出现在第一行的从颈部到左髋部。

蒙太奇(重新调节(改善),“尺寸”,[19 2],“背景色”,“b”,“BorderSize”3)

要可视化PAF与身体的对应关系,请在测试图像上以假彩色显示第一类身体部位对的x和y分量。

idx = 1;损害= horzcat (im, im);pafpair = horzcat(拥堵(:,:2 * idx-1),拥堵(:,:2 * idx));Pafpair = imresize(Pafpair,size(impair,[1 2]));imshowpair (pafpair,损害);

从热图和paf中识别姿势

算法的后处理部分使用神经网络返回的热图和paf来识别图像中人物的个体姿态。

方法获取OpenPose算法的参数getBodyPoseParameters函数作为一个支持文件被附加到示例中。函数返回一个结构参数,如身体部分的数量和身体部位类型之间的连接,参数还包括可以调整的阈值金宝app,以提高算法的性能。

params=getBodyPoseParameters;

通过使用getBodyPoses辅助函数。此函数作为支持文件附加到示例中。辅助函数执行姿势估计的所有后处理步骤:金宝app

  1. 使用非最大值抑制从热图中检测精确的身体部位位置。

  2. 对于每种类型的身体部位配对,在检测到的身体部位之间生成所有可能的配对。例如,在六个颈部和六个左肩部之间生成所有可能的配对。结果是一个二分图。

  3. 通过计算通过PAF向量场连接两个检测到的身体部位的直线的线积分,对这些对进行评分。分数越大,表示检测到的身体部位之间的连接越强。

  4. 根据分数对可能的对进行排序,并找到有效的对。有效的身体部位配对是连接属于同一个人的两个身体部位的配对。通常情况下,分数最大的配对会首先考虑,因为它们最有可能是有效的配对。然而,该算法使用额外的约束来补偿遮挡和接近。例如,同一个人不能有重复的身体部位,一个身体部位不能属于两个不同的人。

  5. 知道身体的哪些部位是相连的,然后将身体的各个部位组装成每个人的独立姿势。

helper函数返回一个三维矩阵。第一个维度表示图像中已识别人员的数量。第二个尺寸表示身体部位类型的数量。第三个维度表示每个人每个身体部位的x和y坐标。如果在图像中未检测到身体部位,则该部位的坐标为[NaN NaN]。

姿势=getBodyPoses(热图、pafs、参数);

使用渲染动态helper函数。这个函数作为支持文件附加到示例中。金宝app

渲染动态姿势(im,姿势,大小(热图,1),大小(热图,2),参数);

工具书类

曹,哲,希内斯·伊达尔戈,托马斯·西蒙,魏世恩和亚瑟·谢赫。OpenPose:使用部分亲和场的实时多人2D姿态估计。ArXiv: 1812.08008 (Cs), 2019年5月30日。https://arxiv.org/abs/1812.08008

[2] CPU上的实时2D多人姿势估计:轻量级OpenPoseArXiv:1811.12004[Cs],2018年11月29日。https://arxiv.org/abs/1811.12004

另见

(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)