const video = document.getElementById('video'); const canvas = document.getElementById('output'); const ctx = canvas.getContext('2d'); async function setupCamera() { video.width = 640; video.height = 480; const stream = await navigator.mediaDevices.getUserMedia({ video: true }); video.srcObject = stream; return new Promise((resolve) => { video.onloadedmetadata = () => { resolve(video); }; }); } async function loadAndPredict() { const net = await posenet.load(); async function detectPose() { const pose = await net.estimateSinglePose(video, { flipHorizontal: false }); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(video, 0, 0, canvas.width, canvas.height); drawKeypoints(pose.keypoints, 0.6, ctx); drawSkeleton(pose.keypoints, 0.7, ctx); requestAnimationFrame(detectPose); } detectPose(); } function drawKeypoints(keypoints, minConfidence, ctx) { keypoints.forEach((keypoint) => { if (keypoint.score >= minConfidence) { const { y, x } = keypoint.position; ctx.beginPath(); ctx.arc(x, y, 5, 0, 2 * Math.PI); ctx.fillStyle = 'red'; ctx.fill(); } }); } function drawSkeleton(keypoints, minConfidence, ctx) { const adjacentKeyPoints = posenet.getAdjacentKeyPoints(keypoints, minConfidence); adjacentKeyPoints.forEach((keypoints) => { drawSegment(keypoints[0].position, keypoints[1].position, ctx); }); } function drawSegment({ y: y1, x: x1 }, { y: y2, x: x2 }, ctx) { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.lineWidth = 2; ctx.strokeStyle = 'green'; ctx.stroke(); } setupCamera().then((video) => { video.play(); video.onplay = () => { canvas.width = video.width; canvas.height = video.height; loadAndPredict(); }; });