TT Lab
ブログ

한국어 English 日本語 中文

はじめる
ブログ

ブログ

人の姿勢 1: ヒートマップで関節を探す — OpenPoseのPAF、HRNet、そしてトップダウン対ボトムアップ

ステータス:ドラフト(2026-10-13)。 論文の数値は原典を開き、条件とともに確認しました。実際に検証した環境はノートPCのCPUによるnumpyのサンプル(code/07_heatmap_decode.py、10秒前後)です。TT Scoreで姿勢モデルを実際に使用した結果は、TT Scoreモデル解剖編4の実測を引用しています。 シリーズ「ビジョンモデルを読む 2」第7回。次の記事: 人の姿勢 2. HRNetの構造(複数の解像度を最後まで並行して維持する点)自体は ビジョンモデルを読む 1で扱っています。本記事は「関節をどのように学習させ、取り出すか」に焦点を当てます。

人の姿勢 1: ヒートマップで関節を探す

目次

1. 直感:座標の代わりにマップ

姿勢推定(pose estimation)とは、画像中の人の関節(鼻、肩、ひじ、手首、腰、ひざ、足首など)の位置を見つけるタスクです。COCOデータセットを基準に、1人あたり17点となります。

最もストレートな方法は、ネットワークに34個の座標(17点 × x, y)を直接出力させることです。2014年のDeepPoseがこれを行いました。人物のバウンディングボックスで正規化した座標を二乗誤差で回帰し、予測の周囲を切り抜いてもう一度修正するステージを設けていました(論文)。

同年、トンプソン(Tompson)らは別のアプローチを提案しました。関節ごとに 図のような形状のマップ(ヒートマップ) を出力させ、正解データも関節の位置に小さなガウス分布の山を描いたマップを作成して、ピクセルごとに二乗誤差で比較しました。そして、座標を直接回帰する方式は高精度な領域において弱いと指摘しました(論文)。それから10年近く、姿勢推定の基本はヒートマップとなりました。

ヒートマップが強力な理由は、TT Scoreモデル解剖編2でボールの検出について説明した内容と同じです。ピクセルごとに学習シグナルが生まれ、「ここではない」ということが自然に表現でき、候補が複数あっても問題ありません。人の姿勢においてはもう一つの利点があります。畳み込みは画像内の位置関係をそのまま維持するため、 位置を位置として出力する表現がネットワークの構造とよく合致するからです。

2. 概要図:複数の人を扱う2つのアプローチ

사람부터 찾나, 관절부터 찾나 위에서 아래로(top-down) 사람 검출기 상자 n개 상자마다 잘라서 한 사람 모델 × n 정확, 시간 ∝ 사람 수 HRNet · RTMPose 아래에서 위로(bottom-up) 그림 전체 한 번만 모든 관절 히트맵 + 묶기 단서(PAF) 사람별로 짝 맞추기 OpenPose 등 PAF(팔다리 친밀도 장) 팔뚝 위 화소마다 「팔꿈치 → 손목」 방향의 단위 벡터 팔꿈치 손목 A 손목 B 후보 선분을 따라 「PAF · 선분 방향」 을 적분해 점수를 낸다 팔꿈치–손목 A 는 높고, B 는 낮다 → A 와 잇는다 팔다리마다 따로 짝 맞추기(헝가리안 알고리즘)
図:トップダウン(人先)とボトムアップ(関節先)、そしてPAFによる関節のグルーピング

画面に複数の人がいる場合、もう一つの問題が生じます。「この手首は誰のものか。」

3. OpenPose:四肢の方向をマップとして描く

OpenPose(Caoら、CVPR 2017)におけるグルーピングの手がかりが PAF(Part Affinity Field、部位親和性場) です。前腕などの四肢ごとに2チャンネルのマップを1つ描きます。前腕の 上にある ピクセルには「ひじから手首の方向」の単位ベクトルを、それ以外のピクセルには0を代入します。人が重なっている場合はベクトルを平均します。

推論時には次のようにグループ化します。

  1. 関節ヒートマップのピークから、ひじの候補と手首の候補を抽出します。
  2. ひじの候補と手首の候補を結ぶ線分ごとに、線分に沿って「PAFベクトル · 線分方向」を積分してスコアを算出します。同じ人の腕であれば、PAFが線分と同じ方向を向くためスコアが高くなります。
  3. 全体を一度に解くことは非常に難しいため(NP困難)、四肢ごとに分けて 二部マッチング(ハンガリアンアルゴリズム)で解き、繋ぎ合わせます(論文)。

学習はシンプルです。関節ヒートマップとPAFの2つのブランチを複数のステージにわたって繰り返し出力させ、 ステージごとに 正解マップとの二乗誤差をとります(中間監督)。ラベルのない人が存在する領域は損失計算から除外します。ラベルがないからといって「関節がない」と教え込んではいけないからです。

速度に関する話も興味深いものです。19人が映る動画においてノートPC用GPUで8.8fpsであり(368×654入力)、9人の場合はグルーピング処理が0.58ms、ネットワークが99.6msでした(論文)。 ネットワークは1回だけで、グルーピングは非常に軽量であるというボトムアップの利点が数値として現れています。

4. 学習方法:ガウス正解とOKS

トップダウンの標準型:SimpleBaselineとHRNet

SimpleBaseline(2018)はその名の通りシンプルです。ResNetの後に逆畳み込み(deconvolution)層を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. 実践:ヒートマップから座標を取り出す

ヒートマップを¼解像度で描く場合、1グリッドは入力画像の4ピクセルに相当します。最も明るいグリッド(argmax)を選ぶだけでも、それだけで最大2ピクセル強の誤差が生じます。これを軽減するための一般的な手法が2つあります。

code/07_heatmap_decode.py を用いて3つの手法を比較しました。真の位置を小数点までランダムに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コンペティション。中サイズの人物においてトップダウンより劣る
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。W32をImageNetの事前学習なしで学習した場合は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、マルチスケール。ヒートマップを½解像度まで拡大して小さな人に対応

ここから2つのことが読み取れます。

7. 限界

8. 我々のプロジェクトとのつながり

TTの一言。 ヒートマップで最も明るいセルだけを選んだ場合、セルが4ピクセルの大きさであれば平均して約1.5ピクセルずれます。「2番目に明るい方向に4分の1セル分移動する」という小さな工夫のコツを1つ使うだけで誤差が半分になり、それがAP 5点の向上につながりました。小さな工夫が大きな違いを生む世界です。

参考文献

ログインするといいねできます

コメント

まだコメントはありません。

ログインするとコメントできます