Skip to content
AF
Free Tool

Pose keypoint playground

Pick a keypoint scheme, click a joint, and see the index and name the same point carries in each of the 9 schemes this site reads from source (BlazePose 33, ML Kit 33, COCO 17, Halpe26, COCO-WholeBody 133, OpenPose BODY_25, OpenPose COCO 18, Apple Vision 2D, Apple Vision 3D), or “not in this scheme”. Then copy a TypeScript or Python dict that maps one scheme’s indices to another’s. Two points are paired only when their names match once lowercased with separators removed, which gives 391 pairs across 34 of the 36 scheme pairs; everything else is listed as unmapped, not guessed.

0 nose01 left_eye12 right_eye23 left_ear34 right_ear45 left_shoulder56 right_shoulder67 left_elbow78 right_elbow89 left_wrist910 right_wrist1011 left_hip1112 right_hip1213 left_knee1314 right_knee1415 left_ankle1516 right_ankle16left_knee
The figure and every dot position are a drawing, not data: they place each point by the words in its name so you can click it. No model output or measurement is shown, and two points drawn in one spot are not thereby the same point. No lines join the dots because the dataset records names and indices, not skeleton connections. Faint dots are positions other schemes use.

COCO 17: 13 left_knee

The same name in every scheme the dataset holds.

SchemeIndexName
BlazePose 3325LEFT_KNEE
ML Kit 3325LEFT_KNEE
COCO 1713left_knee
Halpe2613left_knee
COCO-WholeBody 13313left_knee
OpenPose BODY_25not in this scheme
OpenPose COCO 18not in this scheme
Apple Vision 2Dno indexleftKnee
Apple Vision 3Dno indexleftKnee

“Not in this scheme” means no point with this name: Two points share a crosswalk row only when their names are identical after lowercasing and removing every character that is not a letter or a digit. left_knee, LEFT_KNEE and leftKnee all become leftknee and share a row; MOUTH_LEFT and LEFT_MOUTH, or RShoulder and right_shoulder, do not, and stay unmapped rather than guessed. It is a statement about names, not anatomy. Apple Vision joints are named constants with no numeric index.

All 17 points of COCO 17

COCO 17 → BlazePose 33 as code

17 of 17 COCO 17 points have a name match in BlazePose 33; the other 0 are listed in a comment, not mapped.

// COCO 17 -> BlazePose 33: 17 of 17 COCO 17 points have a name match.
// From the aifitnessapi.com keypoint crosswalk (sources read 2026-10-17): a pair exists
// only where both names match after lowercasing and dropping non-alphanumerics.
// A name match is not a guarantee that two models place the point identically.
// https://aifitnessapi.com/tools/keypoint-playground?from=coco-17&to=blazepose-33
export const COCO_17_TO_BLAZEPOSE_33: Readonly<Record<number, number>> = {
  0: 0,  // nose -> NOSE
  1: 2,  // left_eye -> LEFT_EYE
  2: 5,  // right_eye -> RIGHT_EYE
  3: 7,  // left_ear -> LEFT_EAR
  4: 8,  // right_ear -> RIGHT_EAR
  5: 11,  // left_shoulder -> LEFT_SHOULDER
  6: 12,  // right_shoulder -> RIGHT_SHOULDER
  7: 13,  // left_elbow -> LEFT_ELBOW
  8: 14,  // right_elbow -> RIGHT_ELBOW
  9: 15,  // left_wrist -> LEFT_WRIST
  10: 16,  // right_wrist -> RIGHT_WRIST
  11: 23,  // left_hip -> LEFT_HIP
  12: 24,  // right_hip -> RIGHT_HIP
  13: 25,  // left_knee -> LEFT_KNEE
  14: 26,  // right_knee -> RIGHT_KNEE
  15: 27,  // left_ankle -> LEFT_ANKLE
  16: 28,  // right_ankle -> RIGHT_ANKLE
};
// Every COCO 17 point has a name match in BlazePose 33.

What the mapping is built from

Every index and name comes from this site’s pose keypoint reference, which reads each scheme from the model’s own source file or documentation (321 points, read on 2026-10-17). The pairing rule is that reference’s crosswalk, unchanged: Two points share a crosswalk row only when their names are identical after lowercasing and removing every character that is not a letter or a digit. left_knee, LEFT_KNEE and leftKnee all become leftknee and share a row; MOUTH_LEFT and LEFT_MOUTH, or RShoulder and right_shoulder, do not, and stay unmapped rather than guessed.

So a pair says the two sources use the same name. It does not say the two models put the point in the same place on the body, and it does not join points whose names differ only in style. OpenPose spells sides as L and R (LShoulder), so its points pair with its own two schemes and little else; ML Kit writes LEFT_MOUTH where MediaPipe writes MOUTH_LEFT, so those two stay apart. OpenPose BODY_25 and Apple Vision 3D; OpenPose COCO 18 and Apple Vision 3D share no name at all, and the snippet says so. If you decide two differently named points are the same joint for your model, that is your call to write down; this tool will not make it for you.

Pairs per scheme

How many points of the row’s scheme have a name match in the column’s. The table is symmetric because each crosswalk row holds at most one point per scheme.

Using the snippet

  • The dict maps the first scheme’s index to the second’s. Apple Vision joints have no numeric index, so on that side the key or value is the joint name string as Apple spells it.
  • Points with no name match are named in a comment under the dict and given no value, so a lookup for one of them fails loudly in your code instead of returning a plausible wrong joint.
  • Each snippet carries the source date and a link back to the exact view, so a reviewer can check where it came from. The address bar holds the same state (?from=&to=&joint=) for sharing.
  • A name match does not settle which side a source means. In ML Kit 33, the source’s own description of RIGHT_EYE_INNER reads The landmark which corresponds to the inner left eye. (and 2 more like it). Read the scheme page before converting a trained model’s output.
How this works, and what it sends

The page is static. The 9 schemes and the 53-row crosswalk are built into it at deploy time, and every lookup and snippet is computed in your browser by the same module this site’s tests check against the dataset: that every pair emitted is a crosswalk row and that mapping A to B and back returns every point it started from. Nothing is sent anywhere.

The body is a drawing. Dots are placed from the words in each point’s name and are not measurements or any model’s output. COCO-WholeBody’s face and hand points are listed under the figure rather than drawn, because names like face-12 do not say where the point sits. The dataset has names and indices but no skeleton connections, so no lines are drawn between points.

The underlying data is published under CC BY 4.0 on open datasets, and choosing a model in the first place is covered in pose estimation models compared.

Next step

Turning this into a choice of API:

A free tool from AIFitnessAPI. The full index tables are on the pose keypoint maps; every topic in camera-based tracking is at AI motion tracking.