多人姿态估计反思论文: Simple Pose(一)

2020/7/20

Hey,这篇论文主要从以下三个方面对多人姿态估计进行了创新:

1、数据预处理(坐标点变换和ground truth heatmap生成)过程中的中心点对齐问题。

2、使用多尺度监督引导网络生成热度图(论文中将此视为空间注意力机制)

3、用于keypoint和body part heatmap监督的损失函数:focal L2 loss

今天先分析一下论文中的数据预处理问题。剩下两个问题接下来两天再详细分析。论文Section Definition of Heatmaps 中强调,将像素当作是位于一个1*1单元格(cell)的中心,这一观点遵从经典的图像缩放原则(比如opencv和PIL的resize函数),同时也是OpenPose生成关节点高斯热图时采用的。

中心点对齐的计算方法

我们常常需要得出缩放前后某个像素位置和原始位置的精确坐标值,这时候就需要考虑几何中心点对齐,以下分析都是基于中心点对齐的缩放。缩放过程中,我们需要为目标图像dstImg上的每个像素位置找到与之对应的原图像srcImg的位置,并把srcImg上对应的像素值填入dstImg的该坐标位置处。若映射回原图srcImg的坐标位置不是整数,那么就需要做插值,算出映射回去的非整数坐标位置上的原图上的像素值是多少,因此就会有缩放过程中选择使用几阶插值算法了。

注意:图像坐标系从0开始,0123… 像素分别位于每一个像素单元cell的中心。

上面的公式可以这样理解,对于x坐标的映射关系为:srcX = dstX*(srcX/dstX) + [0+(stride-1)] / 2,其中[]内左侧0srcImg上第一个像素方格的坐标,右侧(stride-1)srcImg上的stride长度的右侧图像坐标,两者的均值就是中间点坐标(因为把像素pixel看成了有面积的cell,那么精确的位置应该在cell中心)。其中stridex=srcW/dstW

为了加强理解,再来一个例子,这个例子是为了说明图像的放大或者缩小将会影响 [0+(stride-1)] / 2 的符号。

下图的例子是把原图放大了,即放大了3/2倍(即stride=2/3),我们来计算一下在dst中的第一个像素位置应该对应于原图src中的位置是(stride-1)/2=-1/6,映射到了原始图像src的第一个像素的左侧了。

为了加强理解,我们用一个真正的2-D图像缩放并采用双线性灰度插值的例子详细说明这个过程。

np_image = np.zeros((5, 5))

np_image[2, 2] = 1.0

image = PIL.Image.fromarray(np_image)

PILImg = torchvision.transforms.functional.resize(image, (10, 10)) #(等价于PIL中的resize)

opencvImg = cv2.resize(np_image, (10, 10)) # 和PIL中的resize相同

我们查看一下np_image矩阵如下:

然后查看一下PILImg或opencvImg如下:

 

以上面(4,4)位置灰度值为例,我们来看这个灰度值是如何计算得到的,见下图:

我们先把变换后的图像中待求位置映射回原图中的位置(1.75, 1.75),然后沿着平行于zoy平面上插值一次,接着再在另一个平行于xoz平面上插值一次,就得到了双线性插值的结果为1*0.75*0.75=0.5625。

注意:图像坐标系从0开始,0123… 像素分别位于每一个像素单元cell的中心。

 

到了这里,就不难理解项目中生成keypoint Gaussian heatmap和body part Gaussian heatmap的这段代码:

# x, y coordinates of centers of bigger grid, stride / 2 -0.5是为了在计算响应图时,使用grid的中心

        self.grid_x = np.arange(width) * stride + stride / 2 - 0.5  # x -> width

        self.grid_y = np.arange(height) * stride + stride / 2 - 0.5  # y -> height

# x ,y indexes (type: int) of heatmap feature maps

        self.Y, self.X = np.mgrid[0:self.config.height:stride, 0:self.config.width:stride]

        # <numpy.lib.index_tricks.MGridClass object> slice操作,比如L[:10:2]10个数,每隔两个取一个

        # # basically we should use center of grid, but in this place classic implementation uses left-top point.

        self.X = self.X + stride / 2 - 0.5

        self.Y = self.Y + stride / 2 - 0.5

上面这段代码位于:https://github.com/jialee93/Improved-Body-Parts/blob/316e71fa93e1dc444b1cfd4fc312c21c13bfe93f/py_cocodata_server/py_data_heatmapper.py#L40

如此一来,我们其实是让网络直接预测输入图像空间下的gaussian peak的采样,并且在预测阶段插值回原始输入分辨率。生成的ground truth heatmap例子:

keypoint heatmap(左)body part heatmap(右)

 

今天时间有限,就先把原作者在知乎的文章分享给大家,接下来两天再详细给大家介绍一下,老规矩还是给大家介绍一下租用GPU做实验的方法,我们是在智星云租用的GPU,使用体验很好。具体大家可以参考:智星云官网: http://www.ai-galaxy.cn/,淘宝店:https://shop36573300.taobao.com/公众号: 智星AI,

PEACE

 

参考文献:

https://zhuanlan.zhihu.com/p/109118177

https://github.com/hellojialee/Improved-Body-Parts

https://arxiv.org/abs/1911.10529

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值