Pose estimation
MediaPipe pose landmarks: all 33 by index
MediaPipe's pose model finds 33 points on a body in every image: eleven on the face, the shoulders, elbows and wrists, three points on each hand, the hips, knees and ankles, and a heel and toe on each foot. Here they all are by index, with what each value means and the mistakes that most often turn good landmarks into wrong angles.
The 33 landmarks
| Index | Name | Region |
|---|---|---|
| 0 | nose | Face |
| 1 | left_eye_inner | Face |
| 2 | left_eye | Face |
| 3 | left_eye_outer | Face |
| 4 | right_eye_inner | Face |
| 5 | right_eye | Face |
| 6 | right_eye_outer | Face |
| 7 | left_ear | Face |
| 8 | right_ear | Face |
| 9 | mouth_left | Face |
| 10 | mouth_right | Face |
| 11 | left_shoulder | Arms |
| 12 | right_shoulder | Arms |
| 13 | left_elbow | Arms |
| 14 | right_elbow | Arms |
| 15 | left_wrist | Arms |
| 16 | right_wrist | Arms |
| 17 | left_pinky | Hands |
| 18 | right_pinky | Hands |
| 19 | left_index | Hands |
| 20 | right_index | Hands |
| 21 | left_thumb | Hands |
| 22 | right_thumb | Hands |
| 23 | left_hip | Legs |
| 24 | right_hip | Legs |
| 25 | left_knee | Legs |
| 26 | right_knee | Legs |
| 27 | left_ankle | Legs |
| 28 | right_ankle | Legs |
| 29 | left_heel | Feet |
| 30 | right_heel | Feet |
| 31 | left_foot_index | Feet |
| 32 | right_foot_index | Feet |
The pattern is easy to keep in your head past the face: from 11 onwards, odd indices are the subject's left and even indices their right, working down the body — shoulders 11/12, elbows 13/14, wrists 15/16, hands 17–22, hips 23/24, knees 25/26, ankles 27/28, heels 29/30, toes 31/32.
What each landmark holds
| Field | Meaning |
|---|---|
| x, y | Position in the image, normalized to 0–1 by the image's width and height. The origin is the top-left corner and y grows downwards. |
| z | Depth relative to the midpoint of the hips, on roughly the same scale as x. Smaller is closer to the camera. Estimated from a single image, so treat it as rough. |
| visibility | How likely the point is to be visible rather than hidden behind something — the other leg, the bike, the body itself. |
| presence | How likely the point is to be in the frame at all. |
Normalized coordinates are convenient and also the most common source of wrong angles. On a portrait 1080×1920 frame, one unit of x is 1,080 pixels and one unit of y is 1,920, so a segment's direction is distorted until you multiply back by the frame size. How to calculate joint angles covers why that matters.
Image landmarks and world landmarks
The pose landmarker returns two sets for each person. Image landmarks (pose_landmarks in Python, landmarks in JavaScript) are the normalized positions described above. World landmarks (pose_world_landmarks, worldLandmarks) are the same 33 points as 3D coordinates in metres, with the origin between the hips.
- Use image landmarks when you are drawing on the video, or measuring an angle in the plane the camera sees — which is what a side-on or front-on movement analysis wants.
- World landmarks are tempting for angles out of the camera's plane, but their depth is inferred from one 2D image. Check them against what you can see before you rely on them.
Left is the subject's left
left_knee is the knee on the person's left, not the one on the left of the picture. Facing the camera, the subject's left side appears on the right of the image. That is the right way round — until a front camera mirrors the preview. Mirror the image, and the model still labels the anatomy correctly, but the left knee is now drawn where the viewer expects the right one. Decide once whether you mirror, and do it after pose estimation, not before.
Every mainstream pose model uses the subject's own left and right: MediaPipe, ML Kit, MoveNet and Apple Vision alike. The engines compared has the full mapping between them.
Reading the landmarks in code
import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python import vision
options = vision.PoseLandmarkerOptions(
base_options=python.BaseOptions(model_asset_path="pose_landmarker_full.task"),
running_mode=vision.RunningMode.IMAGE,
)
with vision.PoseLandmarker.create_from_options(options) as landmarker:
image = mp.Image.create_from_file("frame.jpg")
result = landmarker.detect(image)
if result.pose_landmarks: # one list per detected person
person = result.pose_landmarks[0] # 33 landmarks, index 0–32
knee = person[25] # left_knee
print(knee.x, knee.y, knee.z, knee.visibility)import { FilesetResolver, PoseLandmarker } from "@mediapipe/tasks-vision";
const fileset = await FilesetResolver.forVisionTasks(
"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm"
);
const landmarker = await PoseLandmarker.createFromOptions(fileset, {
baseOptions: { modelAssetPath: "pose_landmarker_lite.task" },
runningMode: "VIDEO",
});
// Once per video frame:
const result = landmarker.detectForVideo(video, performance.now());
const person = result.landmarks[0]; // undefined when nobody is in frame
const leftKnee = person?.[25]; // { x, y, z, visibility }The older Solutions API (mp.solutions.pose) returns the same 33 points in the same order, and names them in the PoseLandmark enum — PoseLandmark.LEFT_KNEE is 25 — which is worth using in place of bare numbers once the code grows.
The same points in other engines
| Body point | MediaPipe, ML Kit | COCO-17 (MoveNet, YOLO-pose) | Apple Vision |
|---|---|---|---|
| nose | 0 | 0 | .nose |
| left / right eye | 2 / 5 | 1 / 2 | .leftEye / .rightEye |
| left / right ear | 7 / 8 | 3 / 4 | .leftEar / .rightEar |
| left / right shoulder | 11 / 12 | 5 / 6 | .leftShoulder / .rightShoulder |
| left / right elbow | 13 / 14 | 7 / 8 | .leftElbow / .rightElbow |
| left / right wrist | 15 / 16 | 9 / 10 | .leftWrist / .rightWrist |
| left / right hip | 23 / 24 | 11 / 12 | .leftHip / .rightHip |
| left / right knee | 25 / 26 | 13 / 14 | .leftKnee / .rightKnee |
| left / right ankle | 27 / 28 | 15 / 16 | .leftAnkle / .rightAnkle |
| hands, heels, toes | 17–22, 29–32 | — | — |
| neck, root (pelvis) | — | — | .neck / .root |
The twelve points from shoulders to ankles are common to all of them, which is why a rep counter built on those twelve runs on any engine. Hands, heels and toes are MediaPipe's own: a wrist or ankle angle needs them.
Landmarks without writing the pipeline
Upload a clip to Markerless and every frame's landmarks come back with it: drawn over the video so you can check what the model saw, and downloadable as JSON or CSV with the frame size recorded, so the pixel conversion is one multiplication away. The same landmarks give fourteen joint angles per frame, and a rep counter you can export to whichever engine your app runs.
Questions
How many landmarks does MediaPipe Pose have?
33, numbered 0 to 32: eleven on the face, six on the arms, six on the hands, six on the legs and four on the feet. The same 33 are returned for every person detected, in the same order, whether or not each point is visible.
What is the difference between visibility and presence?
Presence is how likely the point is to be inside the frame at all. Visibility is how likely it is to be seen rather than hidden behind something. A knee behind a bike frame can be present but not visible. Filter on visibility before you trust an angle that uses the point.
Can MediaPipe Pose track more than one person?
Yes. The Pose Landmarker takes a num_poses option, which defaults to 1. Each detected person gets their own list of 33 landmarks.
Why are my angles from MediaPipe landmarks wrong?
Most often because the angle was calculated in normalized coordinates. x and y are divided by different numbers — the frame's width and its height — so directions are distorted unless you multiply them back to pixels first. The second most common cause is a mirrored image swapping left and right.
Is the z coordinate reliable?
It is a depth estimate from a single 2D image, relative to the hips. It is useful for knowing which of two points is nearer the camera, and much less so for measuring an angle out of the camera's plane.
References
Bazarevsky, V., Grishchenko, I., Raveendran, K., Zhu, T., Zhang, F., & Grundmann, M. (2020). BlazePose: On-device Real-time Body Pose tracking. arXiv:2006.10204.
The model behind MediaPipe's pose landmarks, and where the 33-point topology comes from.
doi:10.48550/arXiv.2006.10204
Lugaresi, C., Tang, J., Nash, H., McClanahan, C., Uboweja, E., Hays, M., Zhang, F., Chang, C.-L., et al. (2019). MediaPipe: A Framework for Building Perception Pipelines. arXiv:1906.08172.
The framework the pose model ships in.
doi:10.48550/arXiv.1906.08172
Lin, T.-Y., Maire, M., Belongie, S., Hays, J., Perona, P., Ramanan, D., et al. (2014). Microsoft COCO: Common Objects in Context. Computer Vision – ECCV 2014, Lecture Notes in Computer Science, 740–755.
The dataset whose 17 keypoints MoveNet, YOLO-pose and most other body models output.
doi:10.1007/978-3-319-10602-1_48