MediaPipe Pose: The Complete 33 Landmark List (Index Reference)
Published: May 2, 2026
For: Developers using MediaPipe / anyone implementing pose estimation
This article is for you if:
- You want the index and location of every MediaPipe Pose landmark
- You only need a few specific joints but don't know their indices
- You want to know how to use the
visibilityscore
TL;DR
- MediaPipe Pose returns 33 landmarks (11 on the face, 12 upper body, 10 lower body)
- Each landmark has four values:
{ x, y, z, visibility } - Joints with
visibilitybelow 0.5 are low-confidence and best skipped - Left/right are from the person's point of view, not the camera's (as if mirrored)
Introduction
When you implement MediaPipe Pose, you keep asking yourself "which index is the shoulder again?" or "is 15 the left or the right?" The official docs have a diagram, but opening it mid-implementation just to double-check is a small hassle.
This article lays out all 33 landmarks in one place, explains how to pick the joints you use most, and shows how to use visibility. It also includes a real example from Pose Mirror.
Landmark list
Full-body layout (text diagram)
0 (nose)
1,3 ---- 2,4 (eyes: inner / outer)
5 6 (eye outer corners)
7 8 (ears)
9 10 (mouth: left / right)
11 --- 12 (shoulders)
/ \
13 14 (elbows)
| |
15 16 (wrists)
17,19,21 18,20,22 (fingers)
23 --- 24 (hips)
/ \
25 26 (knees)
| |
27 28 (ankles)
29,31 30,32 (heels / toes)
Reading left vs. right: odd indices (11, 13, 15...) are the person's left side; even indices (12, 14, 16...) are their right side. Viewed from the front, this is mirror-reversed relative to the camera's view.
Face / head (0–10)
| Index | Part | Notes |
|---|---|---|
| 0 | Nose | Face center; useful for orientation |
| 1 | Left eye (inner) | |
| 2 | Right eye (inner) | |
| 3 | Left eye (outer) | |
| 4 | Right eye (outer) | |
| 5 | Left eye (outer corner) | |
| 6 | Right eye (outer corner) | |
| 7 | Left ear | Often low-accuracy in profile |
| 8 | Right ear | |
| 9 | Mouth (left) | |
| 10 | Mouth (right) |
Upper body (11–22)
| Index | Part | Common pairing |
|---|---|---|
| 11 | Left shoulder | 11→13 (left upper-arm direction) |
| 12 | Right shoulder | 12→14 (right upper-arm direction) |
| 13 | Left elbow | 13→15 (left forearm direction) |
| 14 | Right elbow | 14→16 (right forearm direction) |
| 15 | Left wrist | |
| 16 | Right wrist | |
| 17 | Left hand (index knuckle) | When you need hand detail |
| 18 | Right hand (index knuckle) | |
| 19 | Left hand (pinky knuckle) | |
| 20 | Right hand (pinky knuckle) | |
| 21 | Left thumb | |
| 22 | Right thumb |
Lower body (23–32)
| Index | Part | Common pairing |
|---|---|---|
| 23 | Left hip | 23→25 (left thigh direction) |
| 24 | Right hip | 24→26 (right thigh direction) |
| 25 | Left knee | 25→27 (left shin direction) |
| 26 | Right knee | 26→28 (right shin direction) |
| 27 | Left ankle | |
| 28 | Right ankle | |
| 29 | Left heel | |
| 30 | Right heel | |
| 31 | Left toe | |
| 32 | Right toe |
Accessing landmarks in code
pose.onResults((results) => {
const lm = results.poseLandmarks;
if (!lm) return; // no person detected
// Examples for commonly used joints
const leftShoulder = lm[11]; // { x, y, z, visibility }
const rightShoulder = lm[12];
const leftElbow = lm[13];
const nose = lm[0];
// Check confidence with visibility before using it
if (leftShoulder.visibility > 0.5) {
console.log(
`Left shoulder: x=${leftShoulder.x.toFixed(3)}, y=${leftShoulder.y.toFixed(3)}`
);
}
});
What the coordinates mean:
x,y: normalized to the image size (0–1). Top-left is(0,0), bottom-right is(1,1)z: depth relative to the hips (negative is toward the camera). Less accurate than x, yvisibility: detection confidence for the joint (0–1)
Using visibility correctly
Each landmark's visibility indicates how reliably that joint is captured.
// BAD: ignore visibility and use it as-is (mixes in low-accuracy joints)
const shoulder = { x: lm[11].x, y: lm[11].y };
// GOOD: only use high-confidence joints
if (lm[11].visibility > 0.5) {
const shoulder = { x: lm[11].x, y: lm[11].y };
applyToModel(shoulder);
}
Cases where visibility tends to drop:
| Situation | Affected joints |
|---|---|
| Side-on or back-facing photos | All joints on the hidden side |
| Limbs overlapping the body | The overlapping limbs |
| Part of the body cropped off-screen | Joints in the cropped area |
| Dark or blurry images | Generally lower across the board |
A real example from Pose Mirror
Pose Mirror doesn't use all 33 points — it narrows them to the 12 points that map to the 3D figure's joints.
// The joints Pose Mirror actually uses (12 points)
const jointMap = {
leftShoulder: lm[11],
rightShoulder: lm[12],
leftElbow: lm[13],
rightElbow: lm[14],
leftWrist: lm[15],
rightWrist: lm[16],
leftHip: lm[23],
rightHip: lm[24],
leftKnee: lm[25],
rightKnee: lm[26],
leftAnkle: lm[27],
rightAnkle: lm[28],
};
The face (0–10) isn't used for head orientation, and fine finger motion (17–22) isn't supported yet. Bringing those in would enable more precise pose transfer, including head direction and fingertips.
Summary
- Landmarks use fixed indices 0–32
- Left/right are from the person's viewpoint (as if mirrored)
- Skip joints with
visibility < 0.5— they're low-confidence - The key joints for 3D pose transfer are the 18 points from 11 to 28 (limb roots to ends)
Try Pose Mirror and see how the 33 landmarks get turned into a 3D pose for yourself.
Related (Japanese):
- Driving a 3D pose with MediaPipe (Unity WebGL) — the full Unity integration
- Testing Pose Mirror's AI pose accuracy — a real detection-accuracy report