TT Lab
Blog

한국어 English

Get started
Blog

Blog

Human Pose 1: Finding Keypoints with Heatmaps — OpenPose's PAF, HRNet, and Top-Down vs. Bottom-Up

Status: Draft (2026-10-13). Paper figures were verified by opening the original texts along with their conditions. Hands-on testing was done using a numpy example on a laptop CPU (code/07_heatmap_decode.py, around 10 seconds). The actual results of using pose models in TT Score cite the measurements from Part 4 of the TT Score Model Anatomy. Series "Reading Vision Models 2", Part 7. Next part: Human Pose 2. The architecture of HRNet itself (keeping multiple resolutions side by side until the end) is covered in Reading Vision Models 1. This part focuses on "how keypoints are trained and extracted."

Human Pose 1: Finding Keypoints with Heatmaps

Table of Contents

1. Intuition: Maps Instead of Coordinates

Pose estimation is the task of finding the positions of a person's joints (nose, shoulders, elbows, wrists, hips, knees, ankles, etc.) in an image. Based on the COCO dataset, there are 17 points per person.

The most straightforward method is to have the network directly output 34 coordinates (17 points × x, y). DeepPose did this in 2014. It regressed person-box-normalized coordinates using squared error and included a step to re-crop around the prediction and refine it once more (paper).

The same year, Tompson et al. proposed a different path. They had the network draw maps (heatmaps) shaped like the illustration for each keypoint, created ground truth as maps with small Gaussian hills at the keypoint locations, and compared them pixel by pixel using squared error. They also pointed out that direct coordinate regression is weak in very precise domains (paper). For nearly a decade since then, heatmaps have been the foundation of pose estimation.

The reason heatmaps are powerful is the same as what was explained for ball tracking in TT Score Model Anatomy Part 2. Training signals are generated per pixel, "this is not the place" is naturally expressed, and multiple candidates are allowed. Human pose has one more advantage. Since convolutions preserve the positional relationships in the image, outputs that represent positions as positionsfit the network architecture well.

2. Illustration: Two Paths for Handling Multiple People

사람부터 찾나, 관절부터 찾나 위에서 아래로(top-down) 사람 검출기 상자 n개 상자마다 잘라서 한 사람 모델 × n 정확, 시간 ∝ 사람 수 HRNet · RTMPose 아래에서 위로(bottom-up) 그림 전체 한 번만 모든 관절 히트맵 + 묶기 단서(PAF) 사람별로 짝 맞추기 OpenPose 등 PAF(팔다리 친밀도 장) 팔뚝 위 화소마다 「팔꿈치 → 손목」 방향의 단위 벡터 팔꿈치 손목 A 손목 B 후보 선분을 따라 「PAF · 선분 방향」 을 적분해 점수를 낸다 팔꿈치–손목 A 는 높고, B 는 낮다 → A 와 잇는다 팔다리마다 따로 짝 맞추기(헝가리안 알고리즘)
Illustration: Top-down (person first) vs. Bottom-up (keypoints first), and grouping keypoints with PAF

When there are multiple people on the screen, another problem arises: "Whose wrist is this?"

3. OpenPose: Drawing Limb Directions as Maps

The grouping cue in OpenPose (Cao et al., CVPR 2017) is PAF (Part Affinity Fields) . It draws a 2-channel map for each limb type, such as forearms. Pixels on the forearm receive a unit vector pointing "from the elbow to the wrist," while other pixels receive 0. When people overlap, vectors are averaged.

During testing, grouping works as follows:

  1. Elbow candidates and wrist candidates are extracted from the peaks of the keypoint heatmaps.
  2. For each line segment connecting an elbow and a wrist, scores are computed by integrating "PAF vector · segment direction" along the segment. For limbs belonging to the same person, the PAF aligns with the segment direction, resulting in a high score.
  3. Since solving the entire problem at once is too difficult (NP-hard), it is solved separately for each limb type using bipartite matching(Hungarian algorithm) and then stitched together (paper).

Training is straightforward. Both keypoint heatmaps and PAF branches are output iteratively across multiple stages, and at each stage squared error against the ground truth maps is applied (intermediate supervision). Areas with unlabeled people are masked out in the loss function, because we must not teach the network that "there are no joints" simply because a label is missing.

The speed aspect is also interesting. For a video with 19 people, it achieved 8.8 fps on a laptop GPU (368×654 input), and with 9 people, the grouping step took 0.58 ms while the network took 99.6 ms (paper). The network runs once and grouping is very cheap, clearly demonstrating the advantage of bottom-up approaches.

4. How to Train: Gaussian Targets and OKS

The Standard Top-Down Form: SimpleBaseline and HRNet

SimpleBaseline (2018) is simple as its name implies. It attaches three deconvolution layers after ResNet to produce a 64×48 heatmap (¼ resolution) from a 256×192 input. HRNet (2019) avoids reducing and then increasing resolution; instead, it maintains high-resolution branches all the way through while continuously fusing multiple resolution branches (architecture covered in Series 1).

Training is identical for both.

정답 히트맵 Hⱼ(p) = exp(−‖p − 관절 j 의 위치‖² / (2σ²))     (히트맵 칸 단위)
L = Σⱼ Σ_p (예측 Ĥⱼ(p) − Hⱼ(p))²                              (화소마다 제곱 오차)

The HRNet paper text specifies σ as 1 pixel (the configuration value in the official code was not verified). Augmentation included rotation, 0.65–1.35x scaling, left-right flipping (left and right joint labels must also be swapped), and retaining only the upper or lower body (paper).

Evaluation: OKS and AP

Pose estimation requires a criterion to determine whether a prediction is "correct or incorrect." COCO uses OKS (Object Keypoint Similarity) .

OKS = 관절들에 대한 평균 exp( −d² / (2 · s² · (2σᵢ)²) )
      d = 예측과 정답의 거리, s² = 사람의 면적, σᵢ = 관절마다 정한 상수

σᵢ is a value determined by how consistently people annotate that particular keypoint. Joints with clear locations like wrists (0.062) are small, while ambiguous joints obscured by clothing like hips (0.107) are large. Even with the same distance error, wrists are penalized more heavily. AP is the average precision measured by varying the OKS threshold from 0.50 to 0.95.

5. Hands-on: Extracting Coordinates from Heatmaps

When drawing heatmaps at ¼ resolution, a single grid cell corresponds to 4 input pixels. Selecting the brightest cell (argmax) alone introduces an error of up to over 2 pixels. Two conventions exist to mitigate this:

code/07_heatmap_decode.py , we compared the three methods. Placing the true position randomly down to decimal places 3,000 times, we decoded predictions generated by mixing perfect predictions (with Gaussians drawn at those spots) and noise (standard deviation 0.05) (average error in input pixels, code/07_heatmap_decode.out.txt).

Heatmap (cell = input pixels) σ Noise argmax Quarter-shift DARK
64×48 (4 pixels) 1 None 1.52 0.76 0.00
64×48 (4 pixels) 1 0.05 1.58 0.85 0.20
64×48 (4 pixels) 2 0.05 1.97 1.29 0.21
32×24 (8 pixels) 1 0.05 3.16 1.67 0.41
32×24 (8 pixels) 2 0.05 4.03 2.64 0.41

Even with the same heatmap, simply changing the decoding method changes the error from 1.5 pixels down to 0.2 pixels . The coarser the grid (8 pixels), the larger the difference. DARK's 0.00 is because the target is a perfect Gaussian, making the Taylor expansion fit exactly; actual network outputs are not purely Gaussian, so real-world results are not quite that good.

We converted this error into OKS to see how critical it is for scores (assuming person area is half of a 256×192 box).

오차  2화소: 손목 0.995 · 엉덩이 0.998
오차  4화소: 손목 0.979 · 엉덩이 0.993
오차  8화소: 손목 0.919 · 엉덩이 0.972

At the OKS 0.95 threshold (the strictest AP tier), a wrist error of 4 pixels versus 8 pixels determines whether it is counted as "correct" or "incorrect." This is why a decoding difference of a few pixels translates to several points in AP.

6. Paper Figures

All values are based on COCO's 17 human keypoints and OKS-based AP. Since top-down methods yield results depending on the quality of person bounding boxes, the detector's AP is also listed.

Model AP Conditions (Paper)
OpenPose (bottom-up) test-dev 61.8, journal version 64.2 2016 COCO Challenge. Weaker than top-down for medium-sized people
Associative Embedding (bottom-up) test-dev 65.5 Outputs tag values indicating "whose" each keypoint is alongside heatmaps, multi-scale testing
SimpleBaseline ResNet-152 test-dev 73.7 384×288, person detector AP 60.9
HRNet-W32 / W48 val 74.4 / 76.3 256×192 / 384×288. Training W32 without ImageNet pre-training yields 73.4
HRNet-W48 test-dev 75.5, with external data 77.0 384×288
HRNet-W32 + DARK val 61.2 → 66.9 → 70.7 128×96 input. No shift → quarter-shift → full DARK
HRNet-W32 + DARK val 74.4 → 75.6 256×192 input
HigherHRNet-W48 (bottom-up) test-dev 70.5 640px, multi-scale. Upscales heatmaps to ½ resolution to handle small people

Two observations stand out:

7. Limitations

8. Connection to Our Project

TT a word. If you simply pick the brightest cell in the heatmap, when the cell is 4 pixels, it is off by an average of about 1.5 pixels. A small trick—"one-quarter of a cell toward the second brightest one"—cuts the error in half, which was an AP gain of 5 points. This is an area where small tricks make a big difference.

References

Sign in to like

Comments

No comments yet.

Sign in to leave a comment