フィットネスやリハビリ支援、モーションキャプチャなどで注目される 姿勢推定(Pose Estimation)。
いまや ブラウザだけで、しかも リアルタイム に人体の関節を認識できます。
本記事では Google MediaPipe Tasks Vision を使い、Web カメラ映像から姿勢を推定するアプリを わずか数十行 で実装する方法を紹介します。
引用: https://ai.google.dev/edge/mediapipe/solutions/vision/pose_landmarker?hl=ja
姿勢推定とは?
姿勢推定は画像や映像から 人体 33 点 のランドマーク(鼻・目・肩・肘・手首・股関節・膝・足首など)を検出し、 姿勢や動きを数値化する技術です。
例えばこのようなシーンで活用されます。
-
フィットネスフォームの自動チェック
-
ダンス/ヨガの姿勢分析
-
リハビリの動作評価
-
ゲーム/AR インターフェース
MediaPipe Tasks Vision について
MediaPipeはGoogleが提供する機械学習のマルチメディア処理フレームワークで、高精度な姿勢検出が可能です。MediaPipe Tasks Vision の JavaScript 版は内部で TensorFlow Lite(Wasm + WebGL/GPU) を利用しており、追加で TensorFlow.js を用意する必要はありません。ブラウザに読み込むのは @mediapipe/tasks-vision
のみで OK です。
MediaPipe Tasks Visionを使うメリット
項目 | 説明 |
---|---|
機械学習の環境構築が必要ない | npm → ビルド → ブラウザで即動作 |
WebGL/GPU に対応 | 専用 GPU があれば 20〜30 fps、CPU でも 10 fps 前後 |
3D 座標も取得可 |
worldLandmarks からミリ単位の 3D 座標を取得 |
アプリ構成
[Webカメラ] → [MediaPipe Tasks Vision] → [ランドマーク33点から関節の座標取得] → [Canvas/WebGL 描画]
流れとしては、
-
ブラウザでカメラを起動
-
MediaPipe Tasks Visionでリアルタイム推定
-
キーポイントをCanvasで描画
ライブラリインストール
まずは必要なライブラリをnpmでインストールします。
npm install @mediapipe/tasks-vision
※ TypeScript + React (Vite) プロジェクトを前提にしています
サンプルコード
以下はMediaPipe Tasks Visionを使ったReact用のコード例です。
TypeScript + React
import { useEffect, useRef } from "react";
import {
FilesetResolver,
PoseLandmarker,
DrawingUtils,
} from "@mediapipe/tasks-vision";
export default function App() {
const videoRef = useRef<HTMLVideoElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
let landmarker: PoseLandmarker | undefined;
let stream: MediaStream | undefined;
// 初期化
const init = async () => {
// Wasm バンドルの読み込み
const vision = await FilesetResolver.forVisionTasks(
"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm"
);
// PoseLandmarker 初期化
landmarker = await PoseLandmarker.createFromOptions(vision, {
baseOptions: {
modelAssetPath:
"https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/latest/pose_landmarker_lite.task",
delegate: "GPU", // GPU 利用。CPU しかない環境でも自動フォールバック
},
runningMode: "VIDEO",
numPoses: 1,
});
// カメラ起動
stream = await navigator.mediaDevices.getUserMedia({ video: true });
if (!videoRef.current) return;
videoRef.current.srcObject = stream;
await videoRef.current.play();
// 描画コンテキスト
const canvas = canvasRef.current!;
const ctx2d = canvas.getContext("2d")!;
// GPU 描画を完全に使い切る場合は WebGL2 コンテキストも取得する
// const gl = canvas.getContext("webgl2") as WebGL2RenderingContext;
// const drawer = new DrawingUtils(ctx2d, gl);
const drawer = new DrawingUtils(ctx2d);
// 推定ループ
const detect = () => {
if (!videoRef.current || !landmarker) return;
const ts = performance.now();
const res = landmarker.detectForVideo(videoRef.current, ts);
ctx2d.clearRect(0, 0, canvas.width, canvas.height);
ctx2d.drawImage(videoRef.current, 0, 0, canvas.width, canvas.height);
if (res.landmarks.length) {
const lm = res.landmarks[0];
drawer.drawLandmarks(lm, {
color: "red",
lineWidth: 2,
});
drawer.drawConnectors(lm, PoseLandmarker.POSE_CONNECTIONS);
}
requestAnimationFrame(detect);
};
detect();
};
init();
// クリーンアップ
return () => {
landmarker?.close();
stream?.getTracks().forEach((t) => t.stop());
};
}, []);
return (
<div>
<video
ref={videoRef}
width={640}
height={480}
style={{ display: "none" }}
/>
<canvas ref={canvasRef} width={640} height={480} />
</div>
);
}
実装ポイント
-
delegate: "GPU"
を指定すると WebGL2 が使える環境で自動的に GPU 推論 -
タイムスタンプ を
detectForVideo(…, **ts** )
に渡すことで内部でフレーム同期 -
worldLandmarks
から 3D 座標(ミリメートル単位)が取れるので、転倒検知やスイング解析などにも応用可能 -
useEffect
の return でclose()
とstop()
を呼び出し、メモリとカメラを解放。
応用アイデア
これだけで関節位置がリアルタイムに取得できるので、少し工夫すれば色んな応用が可能です。
アイデア | 実装ヒント |
---|---|
スクワットフォーム判定 | 肩・膝・足首 3 点の角度を計算し閾値チェック |
ヨガポーズのスコア | 各関節角度の目標値との差分を rms 誤差でスコア化 |
リズム運動の可視化 | 腕の y 座標の周期を FFT で解析し bpm を表示 |
3D 転倒検知 | worldLandmarks の胴体 z 座標が急落したら警告 |
特にフィットネス分野では、アプリから動きを指導するニーズが高く、AIによる姿勢認識はUXを大きく向上させます。
パフォーマンスの目安
-
ノート PC/ハイエンドスマホ(WebGL2 + delegate:"GPU")
1280×720 入力で おおむね 20〜30 fps -
ミドル〜エントリースマホ(CPU フォールバック)
640×480 入力で 10〜15 fps 程度
解像度を下げる、modelAssetPath を lite ではなく full/float16 に替える、マルチポーズ検出数を増やすなどで速度と精度のトレードオフを調整できます。
他モデルとの比較 (2025 年時点)
モデル | 特徴 | 精度 | 速度 |
---|---|---|---|
MediaPipe PoseLandmarker (BlazePose v3) | 本記事の実装。Web/モバイル対応、3D 座標取得可 | ◎ | ◎ |
OpenPose | マルチパーソン高精度だが重い。GPU 必須 | ◎ | △ |
PoseNet | 軽量・レガシー。33 点ではなく 17 点 | △ | ○ |
まとめ
- MediaPipe Tasks Vision だけで ブラウザ上のリアルタイム姿勢推定が完結
- 3D 座標まで取得できるため、フィットネス・リハビリ・VR 等の高度なアプリにも応用しやすい
- React なら カメラ起動・推論・描画を数十行で実装可能
Web 技術と組み合わせれば、取得した姿勢データを WebSocket でサーバーに送って解析したり、ゲーム内アバターを動かしたりと、いろんな方向に展開できそうです。
参考
- https://www.npmjs.com/package/%40mediapipe/tasks-vision?utm_source=chatgpt.com
- https://ai.google.dev/edge/api/mediapipe/js/tasks-vision.poselandmarker?utm_source=chatgpt.com
- https://ai.google.dev/edge/mediapipe/solutions/vision/gesture_recognizer/web_js?hl=ja
- https://ai.google.dev/edge/mediapipe/solutions/vision/pose_landmarker?hl=ja
採用拡大中!
アシストエンジニアリングでは一緒に働くフロントエンド、バックエンドのエンジニアを募集しています!
少しでも興味ある方は、カジュアル面談からでもぜひお気軽にお話ししましょう!
お問い合わせはこちらから↓
https://official.assisteng.co.jp/contact/