人体姿态估计中的无偏数据处理.
相较于其他的计算机视觉下游任务(如图像分类、目标检测、语义分割等),姿态估计评测算法性能的指标是直接基于坐标来计算的,因此,姿态估计任务对数据处理方法非常敏感,在选择数据处理方法时也需要谨慎,考虑到图像变换对应的标注信息转变。
本文归纳性地提出了无偏数据处理方法(Unbiased Data Processing, UDP),总结了姿态估计任务中误差存在的两个方面:数据增强引入的偏差以及量化误差。仅通过修正这些误差,在不提出任何新算法的情况下就让HRNet有了很大的性能提升,在top-down方案上涨了1.7AP,在bottom-up方案上涨了2.7AP。

1. 问题提出
在人体姿态估计任务的数据处理中,所使用的图片坐标系往往是基于像素的,由于图像是由一个个像素组成的离散矩阵,使用像素所在的数组下标作为坐标,将图像的左上角作为坐标系的原点$(0, 0)$,用矩阵的长宽来代表图片的长宽。
当进行水平翻转(Flipping)操作时,常规操作是翻转后坐标 = 图片宽度 - 1 - 原始坐标:
joints_3d_flipped[:, 0] = img_width - 1 - joints_3d_flipped[:, 0]
在人体姿态估计任务中,非常普遍使用的一个技巧叫做翻转集成(flipping ensemble):对一张输入图片,会正向输入模型推理一次,再水平翻转图片后推理一次,翻转图片推理的结果再次翻转回去,将两次的结果取平均。这样能让模型的预测结果更加鲁棒,提升一定的准确度。
假如原始图片尺寸为16x16,输入模型的图片尺寸为8x8,Heatmap-based方法通常输出的特征图会是4倍下采样,即输出特征图尺寸为2x2。在原始图片上有一个标注点$(8,8)$,假如模型预测结果是完全正确的,则模型预测的坐标是原始坐标经过8倍下采样,即$(1, 1)$。
然而经过水平翻转后,模型预测结果为:
- $(8, 8)$经过Resize到输入图片尺寸,为$(4, 4)$;
- 进行一次水平翻转操作,坐标计算$8 - 1 - 4 = 3$得到$(3, 4)$;
- 再经过4倍下采样,目标点对应的2x2特征图上的坐标为$(0.75, 1)$,由于模型输出的结果只能是整数,输出解码为$(1, 1)$;
- 再次水平翻转,坐标计算$2 - 1 - 1 = 0$得到$(0, 1)$。
由于下采样的关系,用像素个数来表示坐标轴刻度的方式,会在水平翻转时出现结果无法对齐的问题。
2. 无偏数据处理
为了避免以上问题的出现,作者对整个图片坐标系进行了重新定义,提出在连续空间上定义图片,每一个像素只是连续空间上的一个采样点,因而图片的长宽不再是像素点的个数,而是根据单位长度来计算,此时图片的长宽会等于像素个数减$1$。

当图片发生变换时,由于坐标系上采样点的位置固定,因此就算采样点跟原来没有正好对应的像素,也可以通过插值得到变换后的像素值:

在这种连续的图像坐标系下,常见的图像变换被定义为:
⚪ Cropping
把图片坐标系的原点移动到ROI框的左上角:

\[\begin{gathered}
T_{\text {crop }}(R O I)=\left[\begin{array}{ccc}
1 & 0 & -b x_s+0.5 b w_s \\
0 & 1 & -b y_s+0.5 b h_s \\
0 & 0 & 1
\end{array}\right] \\
\end{gathered}\]
⚪ Resizing
由于图片定义在连续空间上,因此只需要调整采样点的间距,即坐标系的单位长度,就能对图片进行缩放:

\[\begin{gathered}
T_{\text {resize }}\left(w_s, h_s, w_d, h_d\right)=\left[\begin{array}{ccc}
\frac{w_d}{w_s} & 0 & 0 \\
0 & \frac{h_d}{h_s} & 0 \\
0 & 0 & 1
\end{array}\right] \\
\end{gathered}\]
⚪ Rotating
旋转操作由于要保护变换后目标仍在图片内,不会由于旋转跑到画幅外,因此通常的操作流程是:先将坐标轴原点移动到ROI中心,然后以新坐标轴原点进行旋转,旋转结束后,用第一步移动坐标轴变换的逆变换,将坐标轴还原。

\[\begin{aligned}
& T_{\text {rot }}(\theta, R O I) \\
= & T_{d 2 \rightarrow d} T_{d 1 \rightarrow d 2} T_{s \rightarrow d 1} \\
= & {\left[\begin{array}{ccc}
1 & 0 & b x_s \\
0 & -1 & b y_s \\
0 & 0 & 1
\end{array}\right]\left[\begin{array}{ccc}
\cos \theta & \sin \theta & 0 \\
-\sin \theta & \cos \theta & 0 \\
0 & 0 & 1
\end{array}\right]\left[\begin{array}{ccc}
1 & 0 & -b x_s \\
0 & -1 & b y_s \\
0 & 0 & 1
\end{array}\right] } \\
= & {\left[\begin{array}{ccc}
\cos \theta & -\sin \theta & -b x_s \cos \theta+b y_s \sin \theta+b x_s \\
\sin \theta & \cos \theta & -b x_s \sin \theta-b y_s \cos \theta+b y_s \\
0 & 0 & 1
\end{array}\right] }
\end{aligned}\]
⚪ Flipping
水平翻转只需要以图片宽度的一半为轴进行镜像即可:

\[\begin{gathered}
T_{\text {flip }}\left(w_s\right)=\left[\begin{array}{ccc}
-1 & 0 & w_s \\
0 & 1 & 0 \\
0 & 0 & 1
\end{array}\right]
\end{gathered}\]
⚪ 误差验证
用新定义的坐标系和变换矩阵,可以从数学上证明原本水平翻转出现的对齐问题被消除了。
原始图像中的关节点标注$k_s$在不经过水平翻转时,经过以下变换前后是一致的:
- 原始图像$\to$缩放图像$\to$特征图$\to$缩放图像$\to$原始图像
\[\begin{aligned}
\hat{\mathbf{k}}_s & =T_{o \rightarrow s} \hat{\mathbf{k}}_o \\
& =T_{o \rightarrow s} T_{i \rightarrow 0} \mathbf{k}_i \\
& =T_{o \rightarrow s} T_{i \rightarrow o} T_{s \rightarrow i, t e s t} \mathbf{k}_s \\
& =\left[\begin{array}{ccc}
1 & 0 & b x_s-0.5 b w_s \\
0 & 1 & b y_s-0.5 b h_s \\
0 & 0 & 1
\end{array}\right]\left[\begin{array}{ccc}
\frac{b w_s}{w_o} & 0 & 0 \\
0 & \frac{b h_s}{h_o} & 0 \\
0 & 0 & 1
\end{array}\right]\left[\begin{array}{ccc}
\frac{w_o}{w_i} & 0 & 0 \\
0 & \frac{h_o}{h_i} & 0 \\
0 & 0 & 1
\end{array}\right] \\
& {\left[\begin{array}{ccc}
\frac{w_i}{b w_s} & 0 & 0 \\
0 & \frac{h_i}{b h_s} & 0 \\
0 & 0 & 1
\end{array}\right]\left[\begin{array}{ccc}
1 & 0 & -b x_s+0.5 b w_s \\
0 & 1 & -b y_s+0.5 b h_s \\
0 & 0 & 1
\end{array}\right] \mathbf{k}_s } \\
& =\mathbf{k}_s
\end{aligned}\]
加入翻转操作后,关节点标注$k_s$在经过以下变换前后仍然是一致的:
\[\begin{aligned}
\hat{\mathbf{k}}_o^{\prime} & =T_{(o, f l i p) \rightarrow o} \hat{\mathbf{k}}_{o, f l i p} \\
& =T_{(o, f l i p) \rightarrow o} T_{(i, f l i p) \rightarrow(o, f l i p)} \mathbf{k}_{i, f l i p} \\
& =T_{(o, f l i p) \rightarrow o} T_{(i, f l i p) \rightarrow(o, f l i p)} T_{i \rightarrow(i, f l i p)} \mathbf{k}_i \\
& =T_{f l i p}\left(w_o\right) T_{r e s i z e}\left(w_i, h_i, w_o, h_o\right) T_{f l i p}\left(w_i\right) \mathbf{k}_i \\
& =\left[\begin{array}{ccc}
-1 & 0 & w_o \\
0 & 1 & 0 \\
0 & 0 & 1
\end{array}\right]\left[\begin{array}{ccc}
\frac{w_o}{w_i} & 0 & 0 \\
0 & \frac{h_o}{h_i} & 0 \\
0 & 0 & 1
\end{array}\right]\left[\begin{array}{ccc}
-1 & 0 & w_i \\
0 & 1 & 0 \\
0 & 0 & 1
\end{array}\right] \mathbf{k}_i \\
& =\left[\begin{array}{ccc}
\frac{w_o}{w_i} & 0 & 0 \\
0 & \frac{h_o}{h_i} & 0 \\
0 & 0 & 1
\end{array}\right] \mathbf{k}_i \\
& =T_{i \rightarrow o} \mathbf{k}_i \\
& =\hat{\mathbf{k}}_o
\end{aligned}\]
⚪ 训练与测试过程
无偏数据处理建立在三个坐标系下:图像原坐标系$O_s-X_sY_s$、网络输入坐标系$O_i-X_iY_i$与网络输出坐标系$O_o-X_oY_o$。

通过在这些连续坐标系下的变换,可以消除由翻转等数据处理引入的误差。
用之前的例子验证一下。假如原始图片尺寸为16x16(连续坐标系中长宽为$15$),输入模型的图片尺寸为8x8(连续坐标系中长宽为$7$),Heatmap-based方法通常输出的特征图会是4倍下采样,即输出特征图尺寸为2x2。在原始图片上有一个标注点$(8,8)$,假如模型预测结果是完全正确的,则模型预测的坐标是原始坐标经过8倍下采样,即$(1, 1)$。
经过水平翻转后,模型预测结果为:
- 标注点$(8, 8)$经过Resize到输入图片尺寸,坐标计算$8 * 7 /15 = 3.73$得到$(3.73,3.73)$;
- 进行一次水平翻转操作,坐标计算$7 - 3.73 = 3.27$得到$(3.27, 3.73)$;
- 再经过4倍下采样,坐标计算$3.27 * 7 /1 = 0.47,3.73 * 7 /1 = 0.53$得到$(0.47,0.53)$,由于模型输出的结果只能是整数,输出解码为$(0, 1)$;
- 再次水平翻转,坐标计算$1 - 0 = 1$得到$(1, 1)$,翻转引入的误差被消除了。
3. 关键点编解码误差
关键点编解码过程中也有一类常见的误差,称为量化误差(quantization error)。由于Heatmap-based方法分为编码和解码两个步骤,编码是把坐标值渲染成对应位置的高斯概率分布,解码是把模型输出的高斯概率分布图用Argmax得到最大相应点坐标。由于Argmax操作最的结果只能是整数,这就导致了经过下采样的特征图永远不可能得到输入图片尺度的坐标精度。毕竟输入图片上的整数坐标对应到输出尺度上带小数,而Argmax会抹去这个小数,因而产生了误差。
更具体地讲,这种低分辨率导致的问题在于,输出的特征图上最大响应值点坐标并不能正好对应高斯分布的极值点,它们之间存在一个小于1个像素的偏差,由于分辨率低无法表现出来。对于这一类误差,有两种误差修正方案:
⚪ 分类形式
由于Heatmap-based方法的Target和Output都是基于高斯分布假设的,而高斯分布的形状和参数都预先设定好了,可以根据理论上的高斯分布形状,对输出的低分辨率的结果进行信息补全。
⚪ 分类+回归形式
在Heatmap定位的同时,还计算一个回归头部,预测Heatmap极值点跟真实GT的偏移,因而最终模型的预测是定位+回归合并的结果。