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

The 33 MediaPipe pose landmarks, numbered 0 to 32, on a figure facing the viewer01234567891011121314151617181920212223242526272829303132Subject’s rightSubject’s left
Drawn facing you, so the subject's left side is on the right of the picture — the way the model labels it.
IndexNameRegion
0noseFace
1left_eye_innerFace
2left_eyeFace
3left_eye_outerFace
4right_eye_innerFace
5right_eyeFace
6right_eye_outerFace
7left_earFace
8right_earFace
9mouth_leftFace
10mouth_rightFace
11left_shoulderArms
12right_shoulderArms
13left_elbowArms
14right_elbowArms
15left_wristArms
16right_wristArms
17left_pinkyHands
18right_pinkyHands
19left_indexHands
20right_indexHands
21left_thumbHands
22right_thumbHands
23left_hipLegs
24right_hipLegs
25left_kneeLegs
26right_kneeLegs
27left_ankleLegs
28right_ankleLegs
29left_heelFeet
30right_heelFeet
31left_foot_indexFeet
32right_foot_indexFeet
Indices are fixed: landmark 25 is always the left knee, whether or not the knee is visible in the frame.

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

FieldMeaning
x, yPosition 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.
zDepth 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.
visibilityHow likely the point is to be visible rather than hidden behind something — the other leg, the bike, the body itself.
presenceHow 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

Python · MediaPipe Tasks
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)
JavaScript · @mediapipe/tasks-vision
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 pointMediaPipe, ML KitCOCO-17 (MoveNet, YOLO-pose)Apple Vision
nose00.nose
left / right eye2 / 51 / 2.leftEye / .rightEye
left / right ear7 / 83 / 4.leftEar / .rightEar
left / right shoulder11 / 125 / 6.leftShoulder / .rightShoulder
left / right elbow13 / 147 / 8.leftElbow / .rightElbow
left / right wrist15 / 169 / 10.leftWrist / .rightWrist
left / right hip23 / 2411 / 12.leftHip / .rightHip
left / right knee25 / 2613 / 14.leftKnee / .rightKnee
left / right ankle27 / 2815 / 16.leftAnkle / .rightAnkle
hands, heels, toes17–22, 29–32——
neck, root (pelvis)——.neck / .root
ML Kit's pose detection uses the same 33-point topology as MediaPipe. Apple Vision's 2D body pose has 19 joints, including a neck and a root point that the others lack.

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

  1. 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

  2. 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

  3. 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

Next

Get every frame's landmarks from your own clip.