[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络

前言:

最近在开发运动计数APP,需要用到姿态估计相关的算法。于是对这一领域的算法进行了总结。如下图所示为姿态估计的一些经典论文。这其中OpenPose的影响力可以说是非常大的了,由于其开源做的好,论文,代码,教程,文档,模型都非常丰富,因此有很多项目都是基于OpenPose的。并且其bottom-up的核心算法PAF也非常值得学习。本期就对OpenPose进行一个详细的讲解,力争用最白话的语言把内容核心算法讲透彻。

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第1张图片

网络结构

​如下图所示为OpenPose的网络结构:

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第2张图片

首先由主干网络VGG19提取图片的特征,然后进入到stage模块,stage是一些串行的模块,每个模块的结构和功能都是一样的。分成两个branch,一个branch生成pcm,一个branch生成paf。并且每个stage的pcm和paf都会进行loss求解。最后总的loss是所有loss的和。​这里考虑一下为什么需要多个stage呢?理论上第一个stage已经可以输出完整的信息了,为什么还需要后面重复的stages呢。这是因为关键点之间有相互的语义信息,例如在stage1中,可能只检测出了眼睛,但是没有检测出鼻子,在stage2中,由于输入中带有satge1的输出,那么stage2就更有更可能根据眼睛再推测出鼻子的位置,因此后面的stage可以利用前面stage提取的信息,进一步优化检测结果,对于一些比较难检测的关键点很有作用。更直白一点的解释就是所有关键点的检测难易程度是不一样的,有一些眼睛,鼻子等视觉特征非常明显,而有一些关键点可能会随着衣着,遮挡,首饰等有非常大的变化,因此前面的stage检测一些简单的关键点,后面的stage再根据前面检测出的关键点检测更复杂一些的关键点,这是一个渐进优化的过程。

白话PCM

PCM其实就是关键点的热力图。Part confidence map。用来表征关键点的位置。假设需要输出18个人体关键点信息,那么PCM会输出19个通道,最后一个通道作为背景。理论上不输出背景也没有什么关系,但是输出背景有两个好处,一是增加了一个监督信息,有利于网络的学习,二是背景输出继续作为下一个stage的输入,有利于下一个stage获得更好的语义信息。下图是输入一张图片,输出19个PCM的示意图。

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第3张图片

虽然说一个关键点对应的是一个pcm中的一个像素,但是一般不这么做,一般会用高斯核来创建PCM的GroundTruth。如果没有高斯核,那么gt附件的点被强制当做负样本来学习,但是实际上该点对应的感受域(黄色虚线框)其实与gt点对应的感受域(红色虚线框)非常接近,导致神经网络很迷惑,这到底是有还是没有关键点?甚至有的时候由于标注存在误差,可能标注的gt点反而没有旁边的负样本点准确,那么神经网络就更迷惑了,学个XX啊。一会跟我说圆的是苹果,一会有跟我说圆的是梨,让我怎么个学呢?因此用高斯核的PCM ground truth能够非常好的缓解这个问题。因为标签点附件的点已经不是简单的当做负样本,还是根据高斯分布同样作为正样本,只是置信度稍低一点,这更符合逻辑。

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第4张图片

 

白话PAF

PCM是大部分的关键点检测网络里面都会用到的技术,相信很多朋友都已经有所了解,而PAF则是openpose的核心,是openpse区别于其他关键点检测框架的最大特性。中文可以翻译为关键点的亲和力场,用来描述不同关键点之间的亲和力。属于同一个人的不同关节,亲和力大,不同人之间的关节,亲和力小。由于openpose是一个bottom-up的姿态估计网络,也就是先不管关节是谁的,先一股脑的检测出来,然后接下来再确定哪些关节的亲和力大,那么把它们划分为同一个人。如下图所示,由于图片中有两个人的实例,检测出了两个左眼与两个左耳,那么如何进行配对呢?此时就是PAF的作用了,PAF会描述任意两个关节之间的亲和力(例如检测出2个左眼与2个左耳,那么每个左眼都能得到和所有左耳的亲和力,也就是一共有4个亲和力),如下图所示,颜色越黄,表示两个关键点之间的亲和力越强,左耳的1点与左眼的1点亲和力明显大于左眼1与左耳2,因此将左眼1与左耳1进行配对。同样的左耳2与左眼2的亲和力更大,因此将左耳2与左眼2进行配对。

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第5张图片

以上是关于PAF作用的描述,那么究竟PAF是如何实现的呢?实际上并不复杂。为了描述方便(接地气),我这里不使用论文中的描述符号和公式,用最直白,接地气的大白话来描述。openpose首先把各个关节进行了人为的配对,如下图所示,一共19对。可以理解成19根骨骼,每一根骨骼连接了两个关节。一个PAF热图对应一根骨骼。刚开始的时候我怎么也不明白,18个关节直接怎么会连出19根骨骼,最后把所有骨骼画出来才明白。原来有的关节可以在多跟骨骼上面,而且openpose增加了耳朵和肩膀之间的虚拟骨骼。如下图红色连接所表示的虚拟骨骼,所以一共是19根骨骼,也就是19个PAF场。由于PAF是用向量来表示的,因此PAF的输出通道是19*2=38,因为一个向量需要由x和y两个标量表示,因此PAF输出通道是19的2倍。

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第6张图片

PAF具体是怎么表达的呢?来看一根左胯到左膝盖的连接骨骼对应的PAF场,首先我们知道骨骼在真实世界中是有长度和宽度的。长度就是骨骼两端的两个关节之间的距离,那么骨骼的宽度呢?可以通过超参来设置,例如假设该骨骼的宽度为α,那么我们可以定义在骨骼内的点亲和力向量不为0,在骨骼外面的点的亲和力向量为0.

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第7张图片

如上图所示,红色的点在骨骼内,所以在PAF场中就是非零向量,绿色的点在骨骼外面,所以在PAF场中用0向量表示。那么有意义的红色点的向量是多少呢?openpose使用了从一个关节指向另一个关节的单位向量来表示,即图中黄色向量的单位长度向量来表示。因此最终的PAF场如下图所示(蓝色部分为0向量区域):

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第8张图片

如果某一个像素点在多个骨骼内部,那么该像素点的PAF向量取所有向量的均值向量。

 

亲和力的快速计算

虽然有了PAF场,那么如何计算两个关键点之间的亲和力呢?理论是需要该骨骼内的所有向量的积分。但是这样计算量代价太大了,实际上可以通过均匀采样的方式。例如将两个关节之间均匀的分为5段,然后采集4个点的paf向量作为最终的亲和力表示,因为所有骨骼都采样相同的做法,随意最后的亲和力相对大小还是得到保证的。如下图所示,这样的话,计算量可以降低很多。

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第9张图片

 

关键点配对

说实话,刚开始我觉得有了PCM和PAF,那么进行配对应该不是问题,例如通过PCM得到3个左耳,3个左眼,再根据他们之间的PAF亲和力,把亲和力最大的配对就行了。例如下图这样的:

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第10张图片

但实际上,PAF学的没有这么智能,有的时候很多亲和力是比较接近的,根本无法根据最大值来简单的配置。例如左耳点1可能与左眼1的亲和力最大,但是左眼1却与左耳2的亲和力最大。这样的话简单的最大值配对就会出现一些问题。

[多图/秒懂]白话OpenPose,最受欢迎的姿态估计网络_第11张图片

实际上这是图论里面的二分图查找组大匹配问题。因此直接使用匈牙利算法进行最大值匹配即可。关于匈牙利算法,其实也不难理解,网上有很多讲的很好的教程,有兴趣的朋友可以​查阅相关资料。

@end(有共同技术爱好的朋友可以加我微信,共同学习,共同进步: 15158106211)

你可能感兴趣的:(深度学习,姿态估计,pytorch,深度学习,动作识别)