人体姿态估计--OpenPose算法解析

1、人体姿态简介
2、OpenPose论文方案解读
2.1 文章亮点
2.2 网络结构
2.3 loss function
2.4 计算heatmap( S_j^*(p) )与vectormap( L_c^*(p) )
2.5 关节拼接与多人检测(Multi-Person Parsing using PAFs)
3、细节梳理
3.1 COCO人体姿态数据集的格式
3.2 为什么heatmap的channels是19,vectormap的channels是38?
3.3 tf-openpose人体姿态估计标签生成--heatmap--vectormap
3.4 改进
4、参考资料

1、人体姿态简介

人体姿态估计是计算机视觉中一个很基础的问题。从名字的角度来看,可以理解为对“人体”的姿态(关键点,比如头,左手,右脚等)的位置估计。
人体姿态估计可以分为两种思路,
(1)“top-down”,它指先检测人体区域,再检测区域内的人体关键点。
(2)“bottom-up”,它指先检测图片中所有的人体关键点,然后将这些关键点对应到不同的人物个体。这里需要提及一下,第一种方案因为需要对检测出的每个人体区域,分别做前向关键点检测,所以速度较慢,而OpenPose采用的则为第二种方案。

2、OpenPose论文方案解读

2.1 文章亮点

已有"bottom-up"方法缺点:(1)未利用全局上下文先验信息,也即图片中其他人的身体关键点信息;(2)将关键点对应到不同的人物个体,算法复杂度太高。
文章改进点:提出“Part Affinity Fields (PAFs)”,每个像素是2D的向量,用于表征位置和方向信息。基于检测出的关节点和关节联通区域,使用greedy inference算法,可以将这些关节点快速对应到不同人物个体。

2.2 网络结构

整个的技术方案为“two-branch multi-stage CNN”,如图,其中一个分支用于预测打分图confidence maps(S),另外一个分支用于预测Par Affinity Fields(L),也对应着heatmap与vectormap。
S=(S_1,S_2,...,S_j) ,表示heatmap,j表示要检测的关节数(可能加上background);
L=(L_1,L_2,...,L_C) ,表示vectormap,C表示要检测的关节对数。
从图中还可以看出,网络的 stage 1 接收的输入是特征 F ,然后经过 Branch 1Branch 2 网络的处理后分别得到 S_1L_1 。从 stage 2 开始,阶段 t 网络的输入包括三部分: S_{t−1},L_{t−1}, F 。每个阶段网络的输入为:
S^t=\rho^t(F,S^{t-1},L^{t-1}), \forall t\ge2 \\ L^t=\phi^t(F,S^{t-1},L^{t-1}), \forall t\ge2 下图展示了CNN的两个分支计算的结果:
上图(b)中表示检测到的关节点,一个部位对应了一张feature map,请注意图中高亮像素;
上图(c)中表示检测到的一段躯干,同样的一个躯干对应一个feature map。

2.3 Loss function

损失函数是保证网络能收敛的最重要的关键点,因此作者对两分支的损失函数均采用L2 loss。训练时,每个阶段都会产生loss,避免梯度消失;预测时只使用最后一层的输出。公式表示如下:
其中, S_j^*(p) 表示branch1 的label图,也称为heatmap; L_c^*(p) 是branch2 的label图 ,也称为vectormap。另外,考虑到有些训练数据集只标注了图片中部分人物的关节点,因此对损失函数采用了空域加权操作,W表示二值化mask矩阵,当位置p的标签缺失时其值为0,否则值为1。显然,对于未被标记的人物关节点 W(p)=0 ,而被标记的人物关节点和非关节点 W(p)=1 ,所以未被标记的人物关节点不会影响模型的学习过程,整个CNN网络架构的优化目标函数如下,

2.4 计算heatmap( S_j^*(p) )与vectormap( L_c^*(p) )

S_j^*(p) 实际上就是使用2D高斯分布建模,求出一张图像上身体j部位的heatmap,记第k个人的第j个关节的heatmap为 S_{j,k}^*(p)p和x_{j,k} 表示位置信息,则有:
L_c^*(p) 表示了使用part affinity fields(PAF)建模骨骼区域,对于骨骼区域内的每一个像素,使用2D向量同时表征位置和方向信息,这里的方向指代当前骨骼对应的关节点对的连接方向,对应vectormap。以下图的骨骼区域为例

图中绿色虚线框内的区域以点集 p 表示,数学公式如下:
0 \leq v\cdot(p-x_{j1,k}) \leq l_{c,k} \quad and \quad |v\times (p-x_{j1,k})|\ \leq\sigma_l 其中, l_{c,k}=||x_{j2,k}-x_{j1,k}||_2 表示骨骼长度, \sigma_l 表示骨骼的粗细,更多详细的信息可在后文中3.1中得到。

2.5 关节拼接与多人检测(Multi-Person Parsing using PAFs)

经过上述过程,我们已经得到各个关节点的坐标图--heatmap,与关节对连接的vectormap,现在的问题就是如何合理地在推理阶段将各个关节连接成一段骨骼,并将它们组装成一个人?
关节拼接 :对于任意两个关节点位置 d_{j1}d_{j2} ,通过计算PAFs的线性积分来表征骨骼点对的相关性,也即表征了骨骼点对的置信度,公式表示如下, E=\int_{u=0}^{u=1} L_c(p(u)) \cdot \frac{d_{j2}-d_{j1}}{||d_{j2}-d_{j1}||_2}\mathrm{d}u 为了快速计算积分,一般采用均匀采样的方式近似这两个关节点间的相似度, p(u)=(1-u)d_{j1}+ud_{j2} 多人检测 :由于图片中人数不确定,同时伴随遮挡、变形等问题,因此只使用上述计算关节对相似度,只能保证局部最优,因此作者利用greedy relaxation的思想生成全局较优的搭配。具体操作如下:
(1)已知不同关节点的heatmap,也就是不同人的某个关节点的点集;
(2)现在要将不同的点集进行唯一匹配,如:一群表示手肘的点集和手腕的点集,两点集中的点必须存在唯一匹配;
(3) 关节点之间的相关性PAF已知,将关键点作为图的顶点,将关键点之间的相关性PAF看为图的边权,则将多人检测问题转化为二分图匹配问题,并用匈牙利算法求得相连关键点最优匹配。

3.2 为什么heatmap的channels是19,vectormap的channels是38?

由上图可知,COCO数据集总共有18个关键点,17个肢体骨架,但heatmap多了一个背景图,vectormap多了耳朵和肩膀的肢体,为什末要虚构这麽一个肢体呢,因为有时候人体是背对相机的,眼睛这个关键点是不可见的,为了更好的预测耳朵,引入这两个个肢体(也就是关节对:2-16和5-17)。所以总共有19个肢体,应为vectormap为矢量,预测时分为x,y两个分量,所以有19*2=38

3.3 tf-openpose人体姿态估计标签生成--heatmap--vectormap

完全参考 https://blog.csdn.net/m0_37477175/article/details/81236115 ,结合2.4节中vectormap( L_c^*(p) )的计算公式与绿色虚线框内的区域以点集数学公式理解。
关键是叉乘的几何意义是两个向量所组成的平行四边形的面积,所以 |v\times (p-x_{j1,k})|\leq \sigma_l 就表示与向量 v 平行距离为 \sigma_l 的区域,也就是骨骼宽度。

3.4 改进

后来论文作者对网络结构进行了改进,使得效果更好,速度更快,参考文献【11】。

4、参考资料

【1】 Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields
【2】 人体姿态估计的过去、现在和未来
【3】 论文解读-Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields
【4】 Realtime Multi-Person 2D Pose Estimation Using Part Affinity Fields【菜鸟读者】
【5】 知乎:openpose笔记
【6】 openpose论文总结:Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields