🎯 ジェスチャーカスタマイズガイド
MediaPipeの手のトラッキング機能を使って、独自のジェスチャーを作成する方法を学びましょう。
MediaPipeの基礎知識
手のランドマーク(21個のポイント)
MediaPipeは手の21個の特徴 点を追跡します:
8 12 16 20 ← 指先
| | | |
7 11 15 19
| | | |
6 10 14 18
| | | |
5---9---13--17
\ | / /
\ | / /
0 ← 手首
/
1-2-3-4 ← 親指
各ランドマークの意味:
- 0: 手首(WRIST)
- 1-4: 親指(THUMB)
- 5-8: 人差し指(INDEX_FINGER)
- 9-12: 中指(MIDDLE_FINGER)
- 13-16: 薬指(RING_FINGER)
- 17-20: 小指(PINKY)
座標システム
各ランドマークは3つの値を持ちます:
- x: 横方向の位置(0.0〜1.0)
- y: 縦方向の位置(0.0〜1.0)
- z: 深さ(カメラからの距離の推定値)
// ランドマークへのアクセス例
const wrist = results.landmarks[0][0];
console.log(`手首の位置: x=${wrist.x}, y=${wrist.y}, z=${wrist.z}`);
現在のジェスチャー実装
1. 手の傾き検出
function getHandAngle(landmarks) {
const wrist = landmarks[0];
const middleBase = landmarks[9];
// 2点間の角度を計算
const angle = Math.atan2(
middleBase.y - wrist.y,
middleBase.x - wrist.x
);
return angle;
}
// 使用例
const angle = getHandAngle(landmarks);
if (angle < -0.3) {
// 左に傾いている
moveTetrisLeft();
} else if (angle > 0.3) {
// 右に傾いている
moveTetrisRight();
}
2. 指の状態検出
function isFingerOpen(landmarks, fingerTip, fingerBase) {
// 指先が指の付け根より上にあるかチェック
return landmarks[fingerTip].y < landmarks[fingerBase].y;
}
// 人差し指が立っているかチェック
const indexFingerUp = isFingerOpen(landmarks, 8, 6);
if (indexFingerUp) {
rotateTetrisPiece();
}
カスタムジェスチャーの実装
例1:グー(一時停止)
すべての指が閉じているときにゲームを一時停止:
function isFist(landmarks) {
// すべての指先が対応する付け根 より下にあるかチェック
const fingers = [
{ tip: 4, base: 2 }, // 親指
{ tip: 8, base: 6 }, // 人差し指
{ tip: 12, base: 10 }, // 中指
{ tip: 16, base: 14 }, // 薬指
{ tip: 20, base: 18 } // 小指
];
return fingers.every(finger =>
landmarks[finger.tip].y > landmarks[finger.base].y
);
}
// ゲームループ内で使用
if (isFist(landmarks)) {
pauseGame();
}