MediaPipe Pose 33ランドマーク完全ガイド|番号一覧と、公式に載っていない実測の注意点

投稿日: 2026年5月2日(最終更新日: 2026年10月3日)
対象読者: MediaPipe Pose Landmarker を使う開発者 / ポーズ推定を実装したい方

この記事はこんな方向け:

  • 33個のランドマークの番号と部位を確認したい方
  • lite / full / heavy のどれを使えばいいか迷っている方
  • visibility が取れない、奥行き z がおかしい、人物が検出されない、で困っている方

はじめに

自作の3Dデッサン人形アプリ PoseMirror では、写真1枚から MediaPipe Pose Landmarker で33点を取り、3Dモデルの姿勢に変換しています。

作っている途中で何度も詰まったのは、番号の覚え違いよりも、公式ドキュメントに書かれていない挙動のほうでした。visibility を使うつもりで書いたコードが、実は毎回 undefined を読んでいた。写真ではまっすぐ伸びている腕が、3Dモデルでは肘で曲がる。顔が写っていない写真だと、人物そのものが見つからない。

公式ドキュメントにある情報(33点の一覧、出力の意味、3つのモデル)はそのまま整理し、載っていない挙動は Unsplash の人物写真120枚で測って図にしました。

33ランドマーク一覧(公式)

全身の配置図

MediaPipe Pose 33ランドマークの配置図(公式)。正面を向いた棒人形の関節に0〜32の番号が付いている。番号ごとの部位は下の表のとおり

出典:Pose landmark detection guide(Google, CC BY 4.0)

手は手首・小指・人差し指・親指の4点で、手首と小指・人差し指が三角形を作ります。

顔・頭部(0〜10)

番号 公式名 部位
0 nose 鼻
1 left eye (inner) 左目(目頭)
2 left eye 左目(中心)
3 left eye (outer) 左目(目尻)
4 right eye (inner) 右目(目頭)
5 right eye 右目(中心)
6 right eye (outer) 右目(目尻)
7 left ear 左耳
8 right ear 右耳
9 mouth (left) 口の左端
10 mouth (right) 口の右端

上半身(11〜22)

番号 公式名 部位
11 left shoulder 左肩
12 right shoulder 右肩
13 left elbow 左肘
14 right elbow 右肘
15 left wrist 左手首
16 right wrist 右手首
17 left pinky 左手の小指の付け根
18 right pinky 右手の小指の付け根
19 left index 左手の人差し指の付け根
20 right index 右手の人差し指の付け根
21 left thumb 左手の親指
22 right thumb 右手の親指

17〜22 は手の向きが分かる程度の3点です。指の曲げ伸ばしまで取りたいなら、手専用の Hand Landmarker(片手21点)を併用します。

下半身(23〜32)

番号 公式名 部位
23 left hip 左腰
24 right hip 右腰
25 left knee 左膝
26 right knee 右膝
27 left ankle 左足首
28 right ankle 右足首
29 left heel 左かかと
30 right heel 右かかと
31 left foot index 左つま先
32 right foot index 右つま先

出力の中身(公式)

Pose Landmarker は1人につき2種類の座標を返します。

出力 x, y z 原点・単位
landmarks 画像の幅・高さで割った 0〜1 の値 奥行き。値が小さいほどカメラに近い。大きさの目安は x とほぼ同じ z だけ左右の腰の中点が原点
worldLandmarks 実空間の3D座標 同左 左右の腰の中点が原点、単位はメートル

各点には visibility(その点が画像内で見えている=画面内にあって隠れていない確率)が付きます。公式ドキュメントには、検出の確信度を表す presence も出力として書かれています。

主な設定項目は次のとおりです。

設定(Web版の名前) 既定値 意味
runningMode IMAGE IMAGE / VIDEO / LIVE_STREAM
numPoses 1 検出する最大人数
minPoseDetectionConfidence 0.5 人物検出のしきい値
minPosePresenceConfidence 0.5 姿勢が存在するとみなすしきい値
minTrackingConfidence 0.5 動画で前のフレームから追跡を続けるしきい値
outputSegmentationMasks false 人物の切り抜きマスクも出すか

処理は2段構成です。まず人物検出器が「腰の中点」「全身を囲む円の半径」「肩と腰を結ぶ線の傾き」を推定して人物の位置を決め、その範囲を骨格推定モデルに渡します。動画では、検出器が動くのは最初のフレームと人物を見失ったときだけで、それ以外のフレームは前のフレームの骨格から範囲を決めます。

コード例(Tasks API・ブラウザ)

import { PoseLandmarker, FilesetResolver } from "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@1.0.1";

const vision = await FilesetResolver.forVisionTasks(
  "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@1.0.1/wasm"
);
const poseLandmarker = await PoseLandmarker.createFromOptions(vision, {
  baseOptions: {
    modelAssetPath:
      "https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_heavy/float16/1/pose_landmarker_heavy.task",
    delegate: "GPU",
  },
  runningMode: "IMAGE",
  numPoses: 1,
});

const result = poseLandmarker.detect(imageElement);
const lm = result.landmarks[0];        // 画像基準の33点
const world = result.worldLandmarks[0]; // メートル単位の33点
if (lm) {
  const leftShoulder = lm[11]; // { x, y, z, visibility }
  console.log(leftShoulder.x, leftShoulder.y, leftShoulder.visibility);
}

旧版の @mediapipe/pose(pose.onResults(...) で受け取る書き方)の記事も多く出回っていますが、新しく書くなら上の Tasks API を使います。

3つのモデル:lite / full / heavy(公式)

モデル ファイルサイズ※ 精度 PCK@0.2(ヨガ / ダンス / HIIT) 処理時間 Pixel 3 / MacBook Pro 2017
lite 5.8MB 90.2% / 92.5% / 93.5% 20ms / 25ms
full 9.4MB 95.5% / 96.3% / 95.7% 25ms / 27ms
heavy 30.7MB 96.4% / 97.2% / 97.5% 53ms / 38ms

※ファイルサイズは公式に記載がなく、配布URLの .task を2026年10月に実測した値です。精度と処理時間は旧 MediaPipe Pose のドキュメントの値です。

入力サイズは3つとも同じで、人物検出器が 224×224、骨格推定が 256×256 です。

公式に載っていない話(実測)

以下は、Unsplash で集めた人物写真120枚(ダンス・ヨガ・スポーツ・座り・しゃがみ等)を3つのモデルに通して測った結果です。

  • 計測環境: Windows 11 / Chromium(Playwright)/ GeForce RTX 4070 / Core i7-13700F
  • ライブラリ: @mediapipe/tasks-vision 1.0.1(visibility の項のみ複数の版を比較)

1. 古い版では visibility が出力されない

visibility を使うつもりでコードを書いても、ブラウザ版の古い版を読んでいると値は undefined です。heavy モデルで、版ごとに出力のキーを調べました。

@mediapipe/tasks-vision の版 1点あたりのキー
0.10.0 〜 0.10.10 x, y, z のみ
0.10.11 〜 1.0.1 x, y, z, visibility

公式ドキュメントにある presence は、1.0.1 でも各点には付いていませんでした。

lm.visibility > 0.5 のような判定は、undefined > 0.5 が false になるため、古い版では全関節が「見えていない」扱いになります。逆に lm.visibility ?? 1 と既定値を補うコードなら、全関節が「見えている」扱いになります。どちらでもエラーは出ないので、気づきにくい不具合です。

2. lite と heavy の差は「取れる骨格」に出る

同じ2枚の写真に lite / full / heavy の骨格を重ねた比較。1段目のヨガ(上向きの犬のポーズ)では lite と full が脚を見失い、骨格が腕の上に潰れている。heavy だけが床に伸びた脚まで取れている。2段目の逆光のランジでは lite の脚が崩れ、full と heavy は前脚と後ろ脚を取れている。処理時間は lite 30ms・26ms、full 33ms・28ms、heavy 43ms・36ms

1段目のヨガの写真では、lite と full が脚を見失い、骨格が腕の上に潰れています。脚まで取れたのは heavy だけです。2段目の逆光のランジでは、lite だけ脚が崩れました。

120枚全体の数字は次のとおりです。

モデル 検出できた枚数 処理時間(中央値)
lite 88 / 120 31ms
full 85 / 120 33ms
heavy 90 / 120 42ms

検出できた枚数はほとんど変わりません。差が出るのは、検出できた写真で骨格が正しく取れているかどうかのほうです。図のように、lite は「人物は見つけたが脚の位置が違う」という外れ方をします。

PoseMirror は写真1枚を解析するアプリで、動画のように毎秒何十枚も処理する必要がありません。そのため、10ms の差よりも骨格の正しさを取って heavy を使っています。ただし、ファイルサイズは lite の約5倍の 30.7MB あり、初回の読み込みはその分遅くなります。

3. CPU と GPU で、検出できる写真が変わる

baseOptions.delegate を "CPU" にするか "GPU" にするかで、検出できる写真そのものが変わりました。

モデル CPU でだけ検出できた GPU でだけ検出できた
lite 10枚 4枚
full 10枚 5枚
heavy 7枚 7枚

heavy は、検出できた枚数こそ CPU・GPU とも90枚で同じですが、そのうち7枚ずつは違う写真でした。GPU で2回測ると、検出の可否は120枚すべてで一致しました。同じ環境なら毎回同じ結果になるので、偶然のぶれではなく、CPU と GPU の計算の違いで分かれていると考えています(原因までは確かめていません)。

手元で検出できた写真が利用者の環境では検出できない、ということが起こり得ます。不具合の報告を再現するときは、delegate をそろえてから確かめてください。

4. worldLandmarks の奥行きをそのまま使うと、肘がずれる

左は踊っている女性の写真で、画面右下へ伸ばした腕はまっすぐ伸びている。右上は worldLandmarks をそのまま PoseMirror の3D人形に適用した結果で、同じ腕が肘で曲がり、手が腰の近くまで下がっている。右下は z を 1/3 に圧縮した結果で、腕が写真と同じようにまっすぐ伸びている。それぞれ正面と真横から見た図

写真では、画面右下へ伸ばした腕がまっすぐです。worldLandmarks をそのまま3Dモデルに使うと、この腕が肘で曲がり、手が腰の近くまで下がりました(右上)。

ずれの元は奥行き z です。PoseMirror で写真から作ったポーズ20件を調べたところ、肘の角度は写真の見た目より平均 +34.1° ずれ、20件すべてで15°以上ずれていました。x と y は画像上の位置そのものですが、z は1枚の写真から推し量るしかないので、誤差が大きくなるのだと考えています。

そこで、landmarks の x と y をピクセル単位に戻し、z だけを 1/3 に縮めてから3Dモデルに渡すようにしました。同じ20件で、肘のずれは平均 +10.3° まで減りました(右下)。1/3 という値は、VTuber 向けのモーションキャプチャアプリ XR Animator の既定値(pose_model_z_depth_scale = 3)にそろえています。

// 画像座標(px)に戻し、z だけ 1/3 に縮める(z は x と同じ尺度なので幅を掛ける)
const px = lm.map(p => [p.x * imgW, p.y * imgH, (p.z * imgW) / 3]);

ずれる向きは写真によって違います。今回の120枚では、伸ばした腕が曲がる例(図の写真)もあれば、曲げた腕が伸びる例もありました。縮める比率は、自分の用途の写真で測って決めてください。

5. 人物が見つからない写真も、範囲を渡せば半分は取れた

PoseMirror に4枚の写真を通した結果。首から下だけが写った椅子に座る人と、逆さまのヨガのポーズは、予備の検出で骨格が取れた。動きでぶれたランナーの脚と、顔を伏せてマットに伏せている人は、骨格が取れなかった

120枚のうち28枚は、どのモデルでも人物が見つかりませんでした。並べてみると、首から下だけの写真、逆さまのポーズ、画面の中で小さく写った人物、動きでぶれた写真が目立ちます。

人物がはっきり写っていても検出されないのは、前段の人物検出器で落ちているためです。後段の骨格推定モデルは、範囲さえ渡せば骨格を返します。そこで、MediaPipe が人物を見つけられなかったときは、Google の別のモデル MoveNet(17点)で体の位置を取ることにしました。その範囲を MediaPipe の骨格推定モデルに直接渡します。

この予備の検出で、28枚のうち 14枚 が取れました(MediaPipe の骨格推定で取れたもの9枚、MoveNet の17点で代用したもの5枚)。図の左2枚がその例です。ぶれた写真や、顔を伏せてマットに伏せている写真は、予備の検出でも取れませんでした。

6. 隠れた関節も座標は返るが、visibility が下がる

2枚の写真で、関節ごとの visibility を色分けした図。緑は見えている、赤は隠れている。左のダンサーは、頭の後ろに回した手首と、体の陰に隠れた反対側の腕が赤い。右のしゃがんだ人は、膝の陰に隠れた足首とかかとが赤や橙になっている

visibility が出力される版(0.10.11 以降)で、関節ごとの値を色にしました。緑が見えている関節、赤が隠れている関節です。

左のダンサーは、頭の後ろに回した手首と、体の陰になった反対側の腕が赤くなっています。右のしゃがんだ人は、膝の陰に隠れた足首とかかとが赤です。隠れた関節にも座標は返ってきますが、位置は推測です。隠れた関節の座標をそのまま使うか、使わずに補うかは、visibility を見て決めます。

PoseMirror で使っている点

PoseMirror の3Dモデルは、33点のうち23点を使っています。

用途 使う点
頭の向き 0(鼻), 7, 8(両耳)
腕 11〜16(肩・肘・手首)
手の向き 17〜20(小指・人差し指の付け根)
胴体・脚 23〜28(腰・膝・足首)
足の向き 29〜32(かかと・つま先)

目(1〜6)と口(9, 10)は、鼻と耳で頭の向きが決まるため使っていません。親指(21, 22)も、手の向きは小指と人差し指の2点で決まるので使っていません。

まとめ

番号の一覧は公式の図と表で足ります。実装で時間を取られるのは、その外側の挙動です。新しく組むときは、次の順に確かめると手戻りが少なくなります。

まず @mediapipe/tasks-vision の版を見ます。0.10.10 以前だと visibility が出ないので、判定のコードが黙って空振りします。次に delegate を決め、手元の確認も同じ設定で行います。CPU と GPU では検出できる写真が変わるからです。3Dモデルに載せるなら、worldLandmarks の奥行きをそのまま使わず、写真と見比べて z の縮め方を決めます。人物が見つからない写真が多いなら、別のモデルで範囲を渡す予備の検出を足すと、半分ほどは取れるようになります。

この記事の処理は、PoseMirror に写真を1枚ドロップすると試せます。

33点のランドマークが3Dモデルに変わる様子を見られます。

写真を1枚ドロップすると、heavy モデルで解析して3Dデッサン人形に反映します。

▶ 写真から3Dデッサン人形を動かす

関連記事:

参考資料

写真: Unsplash より。Mathilde Langevin、Matea Brajdić、Morgan Petroski、syahmi syahir、Wesley Tingey、Pierre-Antoine FRANCK、Alina Rubo、Chris Yang、SHAYAN Rostami

← Kabe-Tech トップへ