WEBサイトでカメラ(WebCam)画像から「Google MediaPipe/pose.js」を使用して姿勢のランドマークを検出して表示します
カメラ使用を許可してしばらくすると、カメラ映像が表示されます
カメラに全身を映してください。ランドマークを推定表示します。
ソースコード
<!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); //線を描く drawConnectors(ctx, results.poseLandmarks, POSE_CONNECTIONS, {color:'#00F', lineWidth:2}); //ランドマークを描く 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>
ランドマークの戻り値について
onResults関数での引数「results.poseLandmarks」配列は以下の値が入っているようです。
poseLandmarks[0~32].x | 画像の幅に対するランドマークのX座標(0.0から1.0の範囲) |
poseLandmarks[0~32].y | 画像の高さに対するランドマークのY座標(0.0から1.0の範囲) |
poseLandmarks[0~32].z | 深度情報。腰の中点を原点として、値が小さいほどカメラに近くなります(全身モードでのみ予測) |
poseLandmarks[0~32].visibility | ランドマークが画像内でどれだけ見えているかの確率(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 (右足の人差し指) |