This demo detects and displays pose landmarks from WebCam images on a website using Google MediaPipe/pose.js.
After granting camera access, the video feed will appear shortly
Make sure your full body is visible to the camera. The system will estimate and display pose landmarks.
Source Code
<!DOCTYPE html>
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0,user-scalable=yes">
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/control_utils/control_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/pose@0.2/pose.js" crossorigin="anonymous"></script>
<script type="module">
let video,can,ctx;
window.addEventListener('load', async function(event){
video = document.querySelector('.video');
can = document.querySelector('.can');
ctx = can.getContext('2d');
const pose = new Pose({locateFile: function(file){
return `https://cdn.jsdelivr.net/npm/@mediapipe/pose@0.2/${file}`;
}});
pose.setOptions({
upperBodyOnly: false,
smoothLandmarks: true,
minDetectionConfidence: 0.5,
minTrackingConfidence: 0.5
});
pose.onResults(onResults);
const camera = new Camera(video, {
onFrame: async function(){
await pose.send({image: video});
},
width: 640,
height: 480
});
camera.start();
});
function onResults(results) {
ctx.save();
ctx.clearRect(0, 0, can.width, can.height);
ctx.drawImage(results.image, 0, 0, can.width, can.height);
// Draw pose connections (lines)
drawConnectors(ctx, results.poseLandmarks, POSE_CONNECTIONS, {
color: '#00F',
lineWidth: 2
});
// Draw pose landmarks (points)
drawLandmarks(ctx, results.poseLandmarks, {
color: '#F00',
lineWidth: 0,
fillColor: '#800',
radius: 3
});
ctx.restore();
}
</script>
</head>
<body>
<div class="container">
<video class="video" style="display:none;"></video>
<canvas class="can" width="640" height="480" style="transform:scale(-1,1);width:90%;max-width:640px;height:auto;"></canvas>
</div>
</body>
</html>
About the Returned Landmark Values
The results.poseLandmarks array passed to the onResults function contains the following values:
| poseLandmarks[0–32].x | X‑coordinate of the landmark relative to the image width (range: 0.0–1.0) |
| poseLandmarks[0–32].y | Y‑coordinate of the landmark relative to the image height (range: 0.0–1.0) |
| poseLandmarks[0–32].z | Depth value. Using the midpoint of the hips as the origin, smaller values are closer to the camera (predicted only in full‑body mode) |
| poseLandmarks[0–32].visibility | Probability indicating how visible the landmark is within the image (range: 0.0–1.0) |
| poseLandmarks[0] | NOSE |
| poseLandmarks[1] | LEFT_EYE_INNER |
| poseLandmarks[2] | LEFT_EYE |
| poseLandmarks[3] | LEFT_EYE_OUTER |
| poseLandmarks[4] | RIGHT_EYE_INNER |
| poseLandmarks[5] | RIGHT_EYE |
| poseLandmarks[6] | RIGHT_EYE_OUTER |
| poseLandmarks[7] | LEFT_EAR |
| poseLandmarks[8] | RIGHT_EAR |
| poseLandmarks[9] | MOUTH_LEFT |
| poseLandmarks[10] | MOUTH_RIGHT |
| poseLandmarks[11] | LEFT_SHOULDER |
| poseLandmarks[12] | RIGHT_SHOULDER |
| poseLandmarks[13] | LEFT_ELBOW |
| poseLandmarks[14] | RIGHT_ELBOW |
| poseLandmarks[15] | LEFT_WRIST |
| poseLandmarks[16] | RIGHT_WRIST |
| poseLandmarks[17] | LEFT_PINKY |
| poseLandmarks[18] | RIGHT_PINKY |
| poseLandmarks[19] | LEFT_INDEX |
| poseLandmarks[20] | RIGHT_INDEX |
| poseLandmarks[21] | LEFT_THUMB |
| poseLandmarks[22] | RIGHT_THUMB |
| poseLandmarks[23] | LEFT_HIP |
| poseLandmarks[24] | RIGHT_HIP |
| poseLandmarks[25] | LEFT_KNEE |
| poseLandmarks[26] | RIGHT_KNEE |
| poseLandmarks[27] | LEFT_ANKLE |
| poseLandmarks[28] | RIGHT_ANKLE |
| poseLandmarks[29] | LEFT_HEEL |
| poseLandmarks[30] | RIGHT_HEEL |
| poseLandmarks[31] | LEFT_FOOT_INDEX |
| poseLandmarks[32] | RIGHT_FOOT_INDEX |

