8月14日、Roboflowが「How to Build a Local AI Basketball Shot Evaluator」と題した記事を公開した。ラップトップ1台・実費ゼロで、スマートフォンで録画したバスケットボールの動画からシュートの成否・軌道・フォームを自動解析するシステムの構築方法を詳しく解説している。クラウドAPIへの通信は一切なく、動画データがデバイスの外に出ることもない点が最大の特徴だ。
全体構成:4つのパイプラインで「シュートを数値化」する
このシステムは、スマートフォンで録画した動画を入力として、以下の4段階で処理する。
- 検出:RF-DETRオブジェクト検出モデルがボールとリムの位置を毎フレーム特定。RF-DETRキーポイントモデルが手首・肘・肩・腰・膝の位置を追跡する
- 記憶:連続フレーム間で位置・速度・キーポイントの信頼スコアを保持するステートマシン
- 判定:ルールベースの物理モデルがシュートリリース・軌道弧・物理距離・成否を算出
- 出力:イベントをJSON Lines形式でログ保存し、関節角度やリアルタイム速度をオーバーレイしたアノテーション動画を生成
実行環境はラップトップのみ。クラウドAPIへの呼び出しは一切なく、動画がデバイス外に出ることもない。
モデル構成:カスタム検出+ゼロショットキーポイント
ボールとリムの検出には、Roboflow Universe上のアリゾナ大学「Basketball Shooting Robot」データセット(約9,800枚)をもとにRF-DETR-smallをファインチューニングした。学習済みモデルはmAP50が88.84、精度75.7、再現率84.9を達成。テスト映像では飛行中のフレーム774枚のうち759枚(**98.1%**)でボールを検出した。
フォーム解析には、RF-DETR Keypoint(rfdetrパッケージ v1.9.2)を使用。COCOの17キーポイントモデルをそのまま利用しており、追加学習もデータラベリングも不要だ。可視関節のキーポイント信頼スコアは0.98〜1.00を安定して記録し、23回のシュート試技すべてで肘・膝のメトリクスをログできた。
工夫のキモ:物理則を使って「見えない問題」を解く
このシステムで最も興味深いのが、単純な検出だけでは解決できない問題への対処だ。
リムの直径で「ピクセル→メートル」変換
コート上にキャリブレーション用のチェッカーボードを置く代わりに、規定のバスケットリムの内径(18インチ=0.4572メートル)を基準にする。フレーム間でリムのバウンディングボックス幅の中央値を計算し、これをピクセル/メートル変換比として全測定値に適用する。これにより、リリース速度(km/h換算)やリリース高さ(メートル換算)の算出が可能になる。
リリース判定:ポンプフェイクを除外する
「ボールが3フレーム連続で上方向に一定速度以上動いた瞬間」をリリースとする単純ルールでは、ポンプフェイクや大きなドリブルを誤検知した。
修正版では2つの条件を追加している。まず、ボールがシューターの手首から0.35メートル以上物理的に離れていることをリリース条件とした。さらに、ドリブル時の誤検知対策として、ボールの軌道を放物線としてモデリングし、その軌道の延長線がリムのバウンディングボックスに向かっているかを確認する仕組みだ。
ネット遮蔽と落下速度による成否判定
バスケットボールがリムを通過した瞬間、ネットがボールを隠す(オクルージョン)。テストデータでは実際に入った2本のシュートが「ミス」と誤判定された。
ここでニュートンの法則を活用する。自由落下する物体は一定の加速度を持つが、ネットを通過した球はネットの摩擦で落下速度が通常の10〜90%に低下する。この速度減衰を「入った証拠」として使う。
| 判定 | 落下速度の比率 |
|---|---|
| ネットを通過(成功) | 通常の10〜90% |
| リム後方を通過(エアボール) | 通常の100% |
| コート上の別のボール | 0%(静止) |
リム跳ね返りの処理
バウンドしてから入るシュートは当初「ミス→メイク」の2イベントとして記録されていた。現在はボールがリム周辺1リム幅以内でバウンドした場合を特別処理し、「rattled make(バウンドして入った)」または「rattled miss(バウンドして外れた)」として記録する。
セットアップは5ステップ
リポジトリのクローンから起動までの手順は以下の通りだ。uvは高速なPythonパッケージマネージャで、依存解決と仮想環境管理を一体化している。また、Roboflow APIキーはRoboflow公式サイトのアカウント設定から取得できる。
# 1. リポジトリをクローン
git clone https://github.com/aarnavshah12/shot-tracker.git
cd shot-tracker
# 2. Python 3.12の仮想環境を作成
uv venv --python 3.12 .venv
# 3. 依存パッケージをインストール
uv pip install --python .venv -e ".[dev,video,models]"
# 4. APIキーを設定
echo 'ROBOFLOW_API_KEY=your_key_here' > .env
# 5. サーバーを起動
.venv/bin/python -m app.server
起動後はhttp://127.0.0.1:7878にブラウザでアクセスすると、FastAPIベースのダッシュボードが開く。FastAPIはPython製の高速なWebフレームワークで、このプロジェクトではローカルUIとAPIエンドポイントの両方を担っている。動画をドラッグ&ドロップするだけで、総試投数・成功数・成功率・連続成功数がサマリー表示される。
自分でトレーニングから始める場合の流れは次の通りだ。
- Roboflow Universeでバスケットボールデータセットをフォークし、RF-DETR-smallをトレーニング
- リポジトリをクローンし、
.envにAPIキーを追加 models/registry.pyにカスタムモデルIDを記入- スマートフォンをコート端の三脚に固定し、リムが画面上部1/3に入るよう調整して撮影
- ローカルWebインターフェースから動画をアップロード
コスト
実費ゼロ。データセットホスティングとモデルトレーニングはRoboflowの無料枠を使用。モデルの重みは初回ダウンロード後にローカルキャッシュされ、以降の動画処理に追加費用は発生しない。
詳細はHow to Build a Local AI Basketball Shot Evaluatorを参照していただきたい。