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 (右足の人差し指) |

