状态:草稿(2026-10-13)。 论文中的数值是通过打开原文并结合条件进行确认的。亲自实践过的是笔记本 CPU 上的 numpy 示例(
code/07_heatmap_decode.py,大约 10 秒左右)。关于在 TT Score 中实际使用姿态模型的结果,引用了《TT Score 模型解剖》第 4 篇的实际测量数据。 系列「阅读视觉模型 2」第 7 篇。下一篇: 人体姿态 2。HRNet 的结构(将多种分辨率从头到尾并排保留)本身由 阅读视觉模型 1涵盖。本篇专注于「如何训练和提取关节」。
人体姿态 1:通过热力图寻找关节
目录
- 1. 直觉:用地图代替坐标
- 2. 图解:处理多个人的两条路径
- 3. OpenPose:将肢体方向绘制为地图
- 4. 如何训练:高斯真值与 OKS
- 5. 动手实践:从热力图中提取坐标
- 6. 论文数值
- 7. 局限性
- 8. 与我们项目的联系
- 参考资料
1. 直觉:用地图代替坐标
姿态估计(pose estimation)是寻找画中人的关节(鼻子、肩膀、手肘、手腕、臀部、膝盖、脚踝……)位置的任务。以 COCO 数据集为标准,每个人有 17 个点。
最直接的方法是让网络直接输出 34 个坐标(17 个点 × x, y)。2014 年的 DeepPose 就是这么做的。它通过均方误差对齐人脸边界框归一化后的坐标,并设置了重新裁剪预测周边并再次修正的步骤(论文)。
同年,Tompson 等人提出了另一条路径。让每个关节绘制出 如图所示形状的地图(热力图) ,并将真值也制作为在关节位置绘制小型高斯山丘的地图,在每个像素上通过均方误差进行比较。并且他们指出直接回归坐标的方式在极高精度的领域较为薄弱(论文)。在此后的近十年里,姿态估计的基础一直是热力图。
热力图强大的原因与《TT Score 模型解剖》第 2 篇中解释的找球原理相同。每个像素都会产生训练信号,「这里不是」得到了自然的表达,并且候选也可以有多个。对于人体姿态,还有一个额外的原因。由于卷积保持了图像的位置关系, 将位置作为位置输出的输出与网络的结构非常契合。
2. 图解:处理多个人的两条路径
如果画面中有好几个人,就会产生一个额外的问题:「这个手腕是谁的手腕?」
- 从上到下(top-down): 先通过人体检测器找到人体边界框,针对每个边界框裁剪并放大后送入 单人 姿态模型。即使人拍得很小,放大后看也很准确。缺点是时间与人数成正比,检测器漏掉的人就彻底找不到了。
- 从下到上(bottom-up): 一次性绘制整张图中所有关节的热力图,并同时输出将关节 按人头组合的线索。只需运行一次网络,因此即使人很多,耗时也几乎不变。缺点是组合步骤可能会出错,且对小个子的人较弱。
3. OpenPose:将肢体方向绘制为地图
OpenPose(Cao 等人,CVPR 2017)的组合线索是 PAF(Part Affinity Field,肢体亲和场) 。为前臂等每个肢体绘制一个 2 通道地图。在位于前臂 上方 的像素中填入「从手肘到手腕方向」的单位向量,其余像素填入 0。当人物重叠时,对向量求平均。
测试时按如下方式组合:
- 从关节热力图的山峰中提取手肘候选和手腕候选。
- 对于连接一个手肘和一个手腕的每条线段,沿着线段积分「PAF 向量 · 线段方向」来计算得分。如果是同一个人的手臂,PAF 的方向与线段方向相同,得分就会很高。
- 一次性求解整体过于困难(NP-hard),因此针对每个肢体分别通过 二分匹配(匈牙利算法)求解并拼接起来(论文)。
训练很简单。通过多个阶段不断修正并输出关节热力图和 PAF 两个分支,并在 每个阶段 计算与真值地图的均方误差(中间监督)。没有标签的人脸区域会被从损失中屏蔽掉。因为不能教导网络「没有标签就等于没有关节」。
速度方面也很有趣。在包含 19 个人的视频中,笔记本 GPU 达到 8.8fps(368×654 输入),当有 9 个人时,组合步骤耗时 0.58ms,网络耗时 99.6ms(论文)。 网络运行一次且组合成本极低这一 bottom-up 的优点通过数字显现了出来。
4. 如何训练:高斯真值与 OKS
从上到下的标准形态:SimpleBaseline 与 HRNet
SimpleBaseline(2018)顾名思义非常简单。它在 ResNet 后面附加了 3 个反卷积层,从 256×192 的输入中输出 64×48 的热力图(¼ 分辨率)。HRNet(2019)没有缩小再放大分辨率,而是将高分辨率分支一直保留到最后,并持续混合多种分辨率分支(结构见系列 1)。
两者的训练方式相同。
정답 히트맵 Hⱼ(p) = exp(−‖p − 관절 j 의 위치‖² / (2σ²)) (히트맵 칸 단위)
L = Σⱼ Σ_p (예측 Ĥⱼ(p) − Hⱼ(p))² (화소마다 제곱 오차)
HRNet 论文正文中将 σ 记为 1 个像素(官方代码中的设定值未做确认)。数据增强包括旋转、0.65–1.35 倍缩放、左右翻转(左、右关节标签也必须互换)、仅保留上半身或下半身(论文)。
评估:OKS 与 AP
姿态需要标准来判定「正确/错误」。COCO 使用 OKS(Object Keypoint Similarity,目标关键点相似度) 。
OKS = 관절들에 대한 평균 exp( −d² / (2 · s² · (2σᵢ)²) )
d = 예측과 정답의 거리, s² = 사람의 면적, σᵢ = 관절마다 정한 상수
σᵢ 是根据人们拍摄该关节的稳定程度确定的值。像手腕(0.062)这样位置明确的关节较小,而像臀部(0.107)这样被衣服遮挡比较模糊的关节较大。即使距离误差相同,手腕的扣分也会更严重。AP 是将 OKS 阈值从 0.50 变到 0.95 测得的平均精度再次求平均得到的结果。
5. 动手实践:从热力图中提取坐标
如果以 ¼ 分辨率绘制热力图,那么一个网格就相当于输入的 4 个像素。如果选择最亮的网格(argmax),仅此一项就会产生最多 2 个像素左右的误差。有两种惯例可以减少这种误差:
- ¼ 网格偏移: 从最亮的网格出发,向第二亮的邻近方向移动 0.25 个网格。SimpleBaseline 和 HRNet 就是这样做的(论文)。
- DARK(2020): 用高斯函数将预测热力图平滑一次后,在最大值周围对对数值进行二次泰勒展开,以小数形式找到峰值。由于高斯的对数是二次式,因此该计算非常吻合。它还同时建议在绘制真值时,也必须在关节的小数位置绘制山丘(不要进行量化)。
code/07_heatmap_decode.py 对三者进行了比较。将真实位置随机设到小数位共 3,000 次,并解码了在该位置绘制高斯函数的完美预测与混有噪声(标准差 0.05)的预测(以输入像素为单位的平均误差, code/07_heatmap_decode.out.txt).
| 热力图(网格 = 输入多少像素) | σ | 噪声 | argmax | ¼ 网格偏移 | DARK |
|---|---|---|---|---|---|
| 64×48(4 像素) | 1 | 无 | 1.52 | 0.76 | 0.00 |
| 64×48(4 像素) | 1 | 0.05 | 1.58 | 0.85 | 0.20 |
| 64×48(4 像素) | 2 | 0.05 | 1.97 | 1.29 | 0.21 |
| 32×24(8 像素) | 1 | 0.05 | 3.16 | 1.67 | 0.41 |
| 32×24(8 像素) | 2 | 0.05 | 4.03 | 2.64 | 0.41 |
在相同的热力图中, 仅更改解码方式,误差就会从 1.5 像素变化到 0.2 像素 。网格越粗糙(8 像素),差异就越大。DARK 的 0.00 是因为它是完美的高斯分布,泰勒展开完全吻合,而实际网络的输出并非高斯分布,所以没有这么理想。
我们将这个误差换算成了 OKS,以查看其对分数有多重要(假设人体面积为 256×192 边界框的一半)。
오차 2화소: 손목 0.995 · 엉덩이 0.998
오차 4화소: 손목 0.979 · 엉덩이 0.993
오차 8화소: 손목 0.919 · 엉덩이 0.972
在 OKS 0.95 阈值(AP 中最严格的一档)下,4 像素和 8 像素的手腕误差将决定「正确」与「错误」。这就是为什么几个像素的解码差异会体现在好几点 AP 上的原因。
6. 论文数值
全部为 COCO 的 17 个人体关节、基于 OKS 的 AP。由于从上到下方式的结果取决于人体边界框的质量,因此也一并记录了检测器的 AP。
| 模型 | AP | 条件(论文) |
|---|---|---|
| OpenPose(bottom-up) | test-dev 61.8,期刊版 64.2 | 2016 年 COCO 比赛。在中等大小的人体上比 top-down 弱 |
| Associative Embedding(bottom-up) | test-dev 65.5 | 为每个关节额外输出表示「属于谁」的标签值,多尺度测试 |
| SimpleBaseline ResNet-152 | test-dev 73.7 | 384×288,人体检测器 AP 60.9 |
| HRNet-W32 / W48 | val 74.4 / 76.3 | 256×192 / 384×288。若无 ImageNet 预训练来训练 W32 则为 73.4 |
| HRNet-W48 | test-dev 75.5,增加外部数据 77.0 | 384×288 |
| HRNet-W32 + DARK | val 61.2 → 66.9 → 70.7 | 128×96 输入。无偏移 → ¼ 网格偏移 → 完整 DARK |
| HRNet-W32 + DARK | val 74.4 → 75.6 | 256×192 输入 |
| HigherHRNet-W48(bottom-up) | test-dev 70.5 | 640px,多尺度。将热力图放大至 ½ 分辨率以应对小个子人物 |
可以看出两点:
- 输入越小,解码越重要。 DARK 在 128×96 下提升了 +3.8 点,在 256×192 下提升了 +1.2 点。这与前面的示例中网格越粗糙差异越大的情况是一样的。并且仅靠 ¼ 网格偏移一项就从 61.2 提升到了 66.9,达到了 5.7 点。
- top-down 通常更准确。 同期 bottom-up(61.8–70.5)与 top-down(73.7–77.0)之间存在较大差距。不过正如我们在第 8 篇中所看到的,速度和人数的情况有所不同。
7. 局限性
- 热力图成本高昂。 为每个关节绘制 2D 地图,其精度受限于地图的分辨率。提高分辨率会导致计算量呈平方级增加。第 8 篇的 SimCC 正是为了解决这个问题而提出的。
- 快速移动的手臂会产生运动模糊。 在乒乓球挥拍过程中,靠近球拍的手腕在曝光时间内会产生模糊,因而不再是一个「点」。像 BlurBall 这样专门处理球体模糊的装置在人体姿态估计领域并不常见(对比第 9 篇)。
- 遮挡。 被躯干遮挡的另一侧手臂、被球台遮挡的腿经常会出错了。虽然 COCO 标签将遮挡的关节也标记为「存在但不可见」,但要准确预测它们仍然非常困难。
8. 与我们项目的联系
- 实测:当前水平的姿态信号尚不足以改变裁判判定。 在 TT Score 实验中,我们将以球为中心的候选框(而非人体框)输入 RTMPose-m 中,并尝试用「手腕是否在球附近」来过滤反弹候选。结果发现,它几乎无法区分正确答案和伪造结果,过滤后,拉力赛(rally)胜者准确率从 93.1% 下降到 92.0%(60px) 和 87.6%(90px)。如果仅将其用作「需要确认」的提示,未经确认的错误判定从 10 起减少到 6 起,但需要确认的情况增加了 17 个百分点(实际数据来自第 12 篇第 275 场拉力赛,《TT Score 模型解剖》第 4 篇)。
- 对于教练指导,适用 top-down。 练习视频的姿态教练针对的是单一主体,因此 top-down 方法是合适的。服务器端分析使用 RTMDet + RTMPose (top-down),浏览器端使用 MediaPipe(同第 4 篇)。
- 对于比赛,适用二到四人。 单打两人,双打四人。由于人数较少,top-down 的开销并不算大,但单独运行检测器的负担依然存在。像第 8 篇的 RTMO 这种单阶段(one-stage)方法是这个场景的候选方案。
TT 小贴士。 如果只选择热力图中亮度最高的像素,当像素大小为 4 时,平均会有约 1.5 个像素的偏差。只需使用一个名为「向第二亮的方向偏移 1/4 个像素」的小技巧,误差就能减半,这直接带来了 5 点 AP 的提升。小技巧往往能在关键地方产生巨大差异。
参考文献
- Toshev & Szegedy, DeepPose: Human Pose Estimation via Deep Neural Networks, CVPR 2014. https://arxiv.org/abs/1312.4659
- Tompson et al., Joint Training of a Convolutional Network and a Graphical Model for Human Pose Estimation, NeurIPS 2014. https://arxiv.org/abs/1406.2984
- Cao et al., Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields(OpenPose), CVPR 2017. https://arxiv.org/abs/1611.08050 — 期刊版 https://arxiv.org/abs/1812.08008
- Newell et al., Associative Embedding: End-to-End Learning for Joint Detection and Grouping, NeurIPS 2017. https://arxiv.org/abs/1611.05424
- Xiao, Wu, Wei, Simple Baselines for Human Pose Estimation and Tracking, ECCV 2018. https://arxiv.org/abs/1804.06208
- Sun et al., Deep High-Resolution Representation Learning for Human Pose Estimation(HRNet), CVPR 2019. https://arxiv.org/abs/1902.09212
- Zhang et al., Distribution-Aware Coordinate Representation for Human Pose Estimation(DARK), CVPR 2020. https://arxiv.org/abs/1910.06278
- Cheng et al., HigherHRNet: Scale-Aware Representation Learning for Bottom-Up Human Pose Estimation, CVPR 2020. https://arxiv.org/abs/1908.10357
- 示例代码与输出:
code/07_heatmap_decode.py,code/07_heatmap_decode.out.txt