前回の記事「森下翔太の22号ホームランをAIで骨格解析してみた」を読んで、「自分でもやってみたい」と思った方向けの手順解説です。
使うのはGoogleが無料公開している姿勢推定ライブラリ「MediaPipe」。Pythonが少し書ければ、テレビ中継の映像から選手の関節33点の動きをデータ化できます。特別なカメラも有料ソフトも不要です。
必要なもの
- Python(3.9〜3.12あたり)が動くPC
- 解析したいスイングの動画クリップ(数秒でOK)
- ライブラリ4つ(下記コマンドで一発)
pip install mediapipe==0.10.14 opencv-python scipy matplotlib
MediaPipeはバージョン指定がおすすめです。0.10.14までは学習済みモデルが同梱されていて、インストールするだけで動きます(最新版はAPIが変わりモデルの別途ダウンロードが必要)。
ステップ1: 映像を用意する
数秒のスイングクリップを用意します。ここで解析精度の8割が決まるので、ポイントを押さえてください。
- アングルが命。 打者を真横〜斜めから捉えたカットがベスト。センターカメラ(投手側からの正面)でも解析できますが、腰が捕手と重なって精度が落ちます
- 体全体が映っていること。 足元が切れているとステップや重心の解析ができません
- スローリプレイは宝。 フレームあたりの動きが小さくなり、追跡が安定します
なお、放送映像そのものやスクリーンショットをブログ等に掲載するのは著作権的にNGです。映像はあくまで「解析の入力」として使い、公開するのは自分で描いたグラフや骨格図だけにしましょう。
ステップ2: 骨格を抽出する
基本の流れは「動画を1フレームずつ読む → MediaPipeに渡す → 関節座標を保存」です。骨組みはこれだけ。
import cv2
import mediapipe as mp
pose = mp.solutions.pose.Pose(
static_image_mode=True, # 1フレームずつ独立検出(小さい被写体に強い)
model_complexity=1,
min_detection_confidence=0.3,
)
cap = cv2.VideoCapture(“swing_clip.mov”)
while True:
ok, frame = cap.read()
if not ok:
break
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
result = pose.process(rgb)
if result.pose_landmarks:
# 33個の関節座標(x, y, 信頼度)が取れる
landmarks = result.pose_landmarks.landmark
ここで実戦上の重要テクニックを3つ。私が実際にハマったポイントです。
① 打者の周辺だけ切り出して拡大する。 中継映像だと打者は画面の一部にしか映っておらず、そのままでは検出率が上がりません。frame[y:y+h, x:x+w]で打者周辺をクロップし、2倍程度に拡大してからMediaPipeに渡すと検出率が劇的に改善します。私の場合、全体のままだと検出3%だったのが、クロップ+拡大で65%まで上がりました。
② スマホの縦動画は回転に注意。 iPhoneの画面収録などは回転情報がメタデータに入っており、OpenCVはそれを無視して横向きで読み込みます。frame.shapeを確認して、幅と高さが逆ならcv2.rotate()で補正しましょう。
③ 信頼度(visibility)でゴミを弾く。 各関節には0〜1の信頼度が付いてきます。0.5未満の点は誤検出が多いので、集計から除外するのが基本です。
ステップ3: データをグラフにする
関節座標の時系列が取れたら、あとは料理次第です。私の記事で使っている指標は:
- 肩幅・腰幅の変化 — 正面カメラでは体が開くほど見かけの幅が広がるので、「開き」の代理指標になります
- 手首の移動速度 — 座標を時間微分するだけ。ピークがほぼインパクトのタイミングです
- 連続骨格図(キノグラム) — 構え→始動→回転→インパクト→フォローの5局面の骨格を並べた図。matplotlibで関節を線で結ぶだけで作れて、完全な自作画像なので著作権もクリーンです
座標の生データはノイズが乗るので、scipyのsavgol_filter(サビツキー・ゴレイフィルタ)で平滑化してから微分するのがコツです。
正直な限界も知っておく
MediaPipeの出力は2D座標です。カメラに対して奥行き方向の回転は精度が出ません。また、テレビ中継の実効フレームレート(30〜60fps)では、腰と肩の回転開始の数十ミリ秒の差を測るのは分解能的に厳しい。
「測れること」と「測れないこと」を区別して発信するのが、データ解析ブログの信頼の根っこだと思っています。
まとめ
- pip install mediapipe==0.10.14 opencv-python scipy matplotlib
- 横〜斜めアングルのクリップを用意
- クロップ+拡大で検出率を上げて骨格抽出
- visibilityでフィルタして、平滑化してからグラフ化
環境構築からグラフ1枚目まで、慣れれば30分もかかりません。お気に入りの選手のスイングを数字で眺めると、野球観戦の解像度が一段上がりますよ。
解析しながら試合を見るなら、録画でコマ送り確認ができるスカパー!プロ野球セットが個人的にはおすすめです。スマホ中心ならDAZNでも十分楽しめます。
本記事のコードは自由に使ってください。解析結果を公開する際は、放送映像の転載にならないようご注意を。
「スコアの向こう側」は、データ解析で野球観戦がもっと面白くなるブログです。


コメント