ステータス:ドラフト(2026-10-13)、実測値を反映。 この記事の精度と時間は筆者が直接測定した値であり、測定日と条件を表ごとに付記しました。論文の数値は「論文」と別途表示し、測定できなかったものは「未実測」と記載しました。研究が進行中のため、数値は変わる可能性があります。 作成ルール:実測データが基本であり、測定できなかったものは「未実測」と表示します。
目次
- 1. TT Scoreがやること
- 2. 4つのレイヤーに分けた全体図
- 3. 時間予算:16.7msと1.5秒
- 4. レイヤー間を行き来するデータ
- 5. 現在の到達地点:2026-10-13ベースライン
- 6. 今後の方向性
- 7. シリーズの全体像
- 参考
1. TT Scoreがやること
卓球台の脇に三脚でスマホを固定しておくと、画面上のスコアボードがラリーごとに自動でスコアを上げます。判定が曖昧な場合は「確認必要」を表示し、人間が1回タップして修正します。修正の記録は次の学習データとなります。
言葉では簡単ですが、1つのスコアを上げるには機械が次のことをすべて把握していなければなりません。
- ボールが画面のどこにあるか。直径4cm、速ければ時速100kmを超えるボールがフレームごとにどこにあるか。
- 卓球台が画面のどこにあるか。ボールがテーブルに触れたか、どちら側の半分に触れたかを知るには、テーブルの4つの角が必要です。
- 何が起きたか。ボールの軌跡から「バウンド」、「ネット」、「アウト」、「ラリー終了」などのイベントを抽出する必要があります。
- それでどちらが勝ったか。イベントの順序を卓球のルールに照らし合わせ、勝者と理由を決定しなければなりません。
このシリーズでは、これら4つの質問に答えるモデルとルールを1つずつ紐解いていきます。この記事はその全体の地図です。
2. 4つのレイヤーに分けた全体図
| レイヤー | 役割 | 使用するもの | 場所と処理時間 |
|---|---|---|---|
| 第1レイヤー:認識 | フレームからボールの座標と卓球台のコーナーを見つける | ボール:BlurBall。卓球台:人間のタップ、SAM 2.1。補助:姿勢(RTMPose、MediaPipe)、音声(実験) | サーバーGPU、ボール検出ウィンドウ1つにつき10.5ms |
| 第2レイヤー:イベント | ボールの軌跡からバウンド・ネット・アウト・終了を抽出する | 手書きのルール(events.py) |
CPU、1サンプルあたり0.1〜0.4ms |
| 第3レイヤー:ジャッジ | イベントの順序からラリーの勝者と理由を決定する | 卓球のルール(referee.py, rules.py) |
同じCPUプロセス |
| 第4レイヤー:スロー確認 | 曖昧なラリーのみ人間が(今後は Vision-Language Model も)見直す | 人間の1回のタップ | 非同期、スコアの進行をブロックしない |
なぜレイヤーを分けるのか
最大の理由は、 判定ルールがモデルよりも先に正しくなければならないからです。ボールの座標がいくら正確でも、「サーブは自陣に1回、相手陣に1回バウンドしなければならない」といったルールを間違えて実装していればスコアは狂います。そのため、第2レイヤーと第3レイヤーはモデルから切り離し、 純粋なPython関数として配置しました。動画なしで合成軌跡とイベントだけですべてのルールをテストでき、ボールモデルを別のものに差し替えてもジャッジはそのまま機能します。
2つ目の理由は、 故障箇所を切り分けるためです。最初から最後まで1つの大きなモデルが動画を受け取ってスコアを出す場合、間違えたときにボールを見失ったのか、ルールを誤って適用したのかが分かりません。レイヤーに分かれていれば、同じ採点を「モデルが検出したボール」、「正解のボール」、「正解のバウンド」という3つの入力で実行し、どのレイヤーで誤差が生じているかを測定できます。第5章では、この方法により「残る誤差の大半はボール検出ではなくイベント抽出で起きている」ことを示します。
3つ目の理由は、 ライセンスとコストです。レイヤーごとに最小限のツールを選択できます。ボール検出は149万パラメータのモデルで十分であり、ジャッジにGPUは必要ありません。
各レイヤーで何を選び、何を省いたか
| 対象 | 選択した項目 | 選んだ理由 | 省いたものとその理由 |
|---|---|---|---|
| ボール | BlurBall(コードMIT、149万パラメータ) | ブレたボールの 中心にラベル付けする方式であるため、60fpsでの長いブレに対応でき、比較した5つのモデルの中で単体性能が最も優れていた(第2章) | TrackNetV2・MonoTrack・WASB単体:再現率が0.71〜0.96と低かった。同時に動かすと暗い動画で利点があるが、GPU時間が2倍になる |
| 卓球台 | 人間の4回のタップ、実験ではSAM 2.1 tiny(Apache-2.0、3,890万パラメータ) | カメラが固定のため、試合開始時に1回行えば十分である。人間のタップがそのままプロンプトになる(第3章) | YOLO系のセグメンテーションモデル:AGPLの条件。SAM 3:別ライセンス、重みへのアクセス承認が必要、8億4,800万パラメータ |
| 姿勢・ラケット | RTMPose(Apache-2.0)、MediaPipe Pose(コードApache-2.0) | コーチング画面ですでに使用している。スコア判定には「確認必要」のシグナルとしてのみ使用(第4章) | 姿勢によってバウンドを除外すると、勝者の正解率が1.1〜5.5%p低下した |
| 音声 | エンジンに組み込んでいない | クリーンな録音ではテーブルの音を99%判別できるが、実際の練習場の録音では効果が確認できなかった(第6章) | — |
| スロー確認 | 現在は人間 | スコアを変更する権限は人間に持たせる | Vision-Language Modelを判定に活用:基本1秒に1枚を処理するため、バウンドの瞬間が入力に含まれない(第8章) |
3. 時間予算:16.7msと1.5秒
リアルタイムスコアボードには2つの時間制限があります。
- フレーム予算。 60fpsの動画では16.7msごとに新しいフレームが届きます。その時間内に処理しきれない場合、フレームが遅延します。30fpsの場合は33.3msです。
- 判定予算。 ラリーが終了してからスコアが更新されるまでに許容される待ち時間です。目標を1.5秒以内に設定しています。
1フレームに実際にかかる時間
| 部分 | 時間(ウォームアップ後の中央値) | 条件 |
|---|---|---|
| ボール検出、リアルタイム(新フレームごとに直近3枚のウィンドウ1つ) | 10.5ms(fp32)、8.0ms(fp16) | 2026-10-12、サーバーGPU(24GBクラス)が他の負荷のない状態、ウォームアップ30回後の200回×3回の中央値 |
| ボール検出、録画データ(重ならない3枚のウィンドウ、8ウィンドウのバッチ) | フレームあたり3.42ms(1ウィンドウ)、2.81ms(8ウィンドウバッチ) | 2026-10-11、同GPU。1つのウィンドウが3フレームをまとめて処理するため、フレームあたりの値はウィンドウ処理時間の約3分の1 |
| ボール検出、同カードを他のタスクと共有する場合 | ウィンドウ1つにつき40〜46ms | 2026-10-11、音声合成1つとセグメンテーション実験2〜3つが同時に実行されていた時 |
| イベント+ジャッジ(直近2.5秒をサンプルごとに再実行) | サンプルあたり0.118ms(中央値)、0.422ms(95パーセンタイル) | 2026-10-13、ノートPC CPU、32万サンプル |
2行のボール検出時間に3倍の差がある理由が、リアルタイム設計の核心です。BlurBallは3フレームを受け取り、3枚のヒートマップを出力します。録画データの場合はウィンドウを重ならないように3枚ずつずらして処理すればよいですが、リアルタイムでは新しいフレームが届くたびに「今届いたフレームを含む直近の3枚」でウィンドウを新たに実行し、最後のヒートマップのみを使用します。遅延を1フレーム間隔以内に抑える代わりに、GPUの処理量を3倍にするという選択です。中央のヒートマップを使用すれば前後のフレームを両方確認できますが、1フレーム余分に待つ必要があり、両方式のボール検出の差は実測で1%未満でした(約300フレームのサンプル)。
要約すると、空き状態のカードであれば1セッションが60fpsの予算の約63%(10.5 / 16.7ms)を使用します。同じカードを他のタスクと共有すると、1つのウィンドウが40msを超え、60fpsどころか30fpsすら維持できなくなります。そのため、実装では 遅延したウィンドウをキューイングせずに破棄します。 次に実行するウィンドウ用のスロットを1つだけ確保し、GPUの処理が追いつかない場合は新しいウィンドウがそのスロットを上書きします。キューイングすると遅延が際限なく増大するためです。2026-10-11の測定では、処理速度が30fpsに満たなかった分(送信されたフレームの22〜28%)が破棄され、遅延はその分増加しませんでした。
現在のリアルタイムデモでは、ブラウザ側で512×288に縮小したJPEG(品質0.7、実測12〜18KB)を30fps間隔で送信しています。元画像をそのまま送信すると回線帯域が10倍以上かかり、サーバー側での縮小処理の負荷が増大するためです。開発環境においてブラウザからの送信から応答受信までの時間は中央値65ms、90パーセンタイルで84msでした。実際のインターネットを経由する運用経路ではホップ数が異なるため未実測です。
判定までにかかる時間
イベントレイヤーは、「最後のバウンドから1.5秒間新しいバウンドがなければラリー終了」というルールを使用します。1.5秒という値は、実際の試合12編におけるラリー内のバウンド間隔の98%(1,087件中1,066件)をカバーする値です。ただし、これは最も遅いケースです。ボールがテーブルの外に落ちた場合は「アウト」、ボールが画面から消えた場合は「ボールなし」による終了がより早く検出されます。
2026-10-13に実際の配信経路(下記の第4節)で測定した判定遅延は以下の通りです。判定遅延とは、判定を出したイベントが発生した時刻から、人間がラベル付けしたラリー終了時刻を引いた値です。
| 範囲 | 判定遅延中央値 | 90% | 1.5秒以内 |
|---|---|---|---|
| 実際の試合12編、275ラリー | 0.16秒 | 1.23秒 | 98.9% |
| そのうちテスト試合7試合、57ラリー | 0.39秒 | 1.32秒 | 100% |
計算時間とネットワーク時間を除いた、アルゴリズムの待機時間のみの値です。
4. レイヤー間を行き来するデータ
レイヤーを分割すると、レイヤー間の「契約」が重要になります。実際にやり取りされる値は以下の通りです。
| 境界 | データ形式 | 備考 |
|---|---|---|
| ブラウザ → 第1レイヤー | 512×288 JPEG、シーケンス番号、撮影時刻(ms) | 120KBを超えた場合は破棄 |
| 第1レイヤー → 第2レイヤー | フレームごとに (t, x, y, conf) |
ボールがない場合はx・yが空。ブレの長さや角度も出力されるが、現在のエンジンでは使用していない |
| 卓球台 → 第2・第3レイヤー | 4つのコーナー → 画面からテーブル平面への変換 | 試合開始時に1回 |
| 第2レイヤー → 第3レイヤー | Event(t, kind, side, conf, vx, vx_in) |
kindはbounce・net・out・end。vxはバウンド直後のテーブル長手方向の速度(テーブル長/秒) |
| 第3レイヤー → スコアボード | PointCall(winner_side, reason, confidence, t) |
winner_sideが空の場合はレット。信頼度が0.6未満の場合は確認必要 |
2つの点が際立っています。第1に、第2レイヤーは ボールの座標のみ を受け取ります。動画の画素は第1レイヤーを越えて伝わりません。第2に、バウンドイベントに「横方向の速度」が含まれています。ジャッジはこの値を使用して、「サーブのようにネット方向に向かうボール」と「相手にボールを返すボール」を区別します。この単一の数値によって、実際の試合における誤判定が大幅に削減されました(第5章)。
5. 現在の到達地点:2026-10-13ベースライン
公開データセット OpenTTGames の実際の試合 12 編(学習用 5 編、テスト用 7 編)と、その上にラリー終了原因を付与した Extended OpenTTGames ラベルで計測しました。サーバーを特定できるラリー 275 件が対象で、主要指標は ラリー勝者正解率です。
| パス | 勝者一致 | 確認不要で不正解 | 確認必要 | 判定なし |
|---|---|---|---|---|
| 録画採点(ラリーを最後まで見た後に判定) | 91.3% (251/275) | 13 | 108 | 3 |
| 配信されたリアルタイムパス(直近 2.5 秒をサンプルごとに再実行) | 90.2% (248/275) | 15 | 129 | 2 |
| テスト 7 試合のみ、配信パス | 87.7% (50/57) | 6 | 26 | 1 |
条件:ボール座標は BlurBall 事前学習済み重みをそのまま使用(ファインチューニングなし)、卓球台のコーナーはデータセットのセグメンテーションマスクから取得したもの、エンジンは 2026-10-13 版。ノートPCの CPU でエンジンのみ再実行しました。
この数値を読み取る際に留意すべき点が 4 つあります。
- 同じエンジンでもパスによって異なる。 録画採点とリアルタイムパスはクリーンな映像で 3 ラリーの差があり、暗い条件やぼやけた条件では 2 つのパスの順序が逆転しました。そのため、今後のすべての実験では両方のパスを併記します。
- サンプル内のスコアである。 ルールエンジンはこの 12 編を見ながら調整されました。テスト用の 7 試合も同様であるため、この精度は初見の映像に対するパフォーマンスよりも楽観的なものとなっています。
- 単一の体育館、単一の角度である。 OpenTTGames は 1 つの会場で固定された側面カメラ、120fps で撮影されています(60fps に縮小して使用)。スマートフォン、地域の卓球場の照明、異なる角度でのパフォーマンスは未計測です。BlurBall の学習映像 26 編のリストが公開されていないため、OpenTTGames と重複している可能性もあります。
- コーナーが変わると数値が変わる。 2026-10-12 に SAM 2.1 で取得したコーナーを使用した録画採点は 93.1%(256/275)でした。そのコーナーファイルが残っていないため、ベースラインはデータセットマスクのコーナーで再設定しました。コーナーの品質がスコアにどの程度影響するかについては、第 3 編と第 5 編で取り上げます。
6. 今後の方向性
残りの誤差の大部分はボールの検出ではなく イベント抽出で発生します(第 5 編)。そのため、次の段階の関心は「ボールをより良く見つけるモデル」ではなく、「バウンドと打球を区別し、ルール上不可能な順序を除外するシグナル」にあります。2026-10-13 時点のモデル調査における権限構造は 3 行です。以下は調査と設計であり、効果はまだ計測していません(進行中)。
- 認識。 シグナルごとに確率と「信頼性」(0〜1、このシグナルを現在信頼できるか)を個別に算出する。ボールは BlurBall を常時使用し、遮蔽や暗い環境のときのみ 2 つ目のボールモデルを有効にする。ラケット・姿勢、音声(onset +表面分類、同期と信頼性判定が先)、卓球台の平面を追加する。
- イベント → 審判。 現在のルールベースの判定を、卓球ラリーの順序を許可された遷移として組み込んだ 制約付き Viterbi デコーディングに変更する。最適パスと 2 番目のパスのスコア差が小さい場合は「確認必要」(第 5 編第 5 節)。
- 低速な確認。 確認が必要なラリーのクリップのみをビジョン言語モデルに送信してクロスチェックを行い、審判と異なる場合はフラグを立てる(第 8 編)。
同じ調査で挙げられた 5 つの候補は、ルール文法を組み込んだ制約付き Viterbi、高精度イベント位置検出モデル(AdaSpot 系)、音声表面分類と音声・映像同期、ラケット 5 点(RacketVision)、遮蔽対応ボール追跡(TOTNet)です。1 つずつ同じベースライン(第 5 節)と 2 つの同じパスで再計測し、このシリーズに追加していきます。
7. シリーズ構成
| 編 | 内容 |
|---|---|
| 第 2 編 ボール検出 | TrackNet → WASB → BlurBall。ヒートマップ回帰、複数フレーム入力、ブラー中心ラベル、HRNet |
| 第 3 編 卓球台検出 | SAM 2.1、EfficientTAM、SAM 3。プロンプトセグメンテーション、メモリアテンション、マスクからの 4 コーナーとホモグラフィ |
| 第 4 編 姿勢とラケット | RTMPose(SimCC)、MediaPipe、RacketVision のラケット 5 点 |
| 第 5 編 イベントと審判 | 軌跡からのバウンド・打球の抽出ルール、審判エンジン、精度が 66.9% から向上した経緯、3D 極値ルールと制約付き Viterbi |
| 第 6 編 音声 | onset 検出と表面分類。実際の録音で効果が見られなかったというネガティブな結果 |
| 第 7 編 データセット | OpenTTGames、Extended、T3Set、TT Sounds、RacketVision、LATTE-MV の実測表と落とし穴 |
| 第 8 編 ビジョン言語モデル | なぜ判定を任せないのか |
一言まとめ: ボールをうまく見つけることと、上手にスコアをつけることは別の問題です。このシリーズでは、その間のギャップを数値でたどっていきます。
参考
- このシリーズのコードパスは TT Score エンジンフォルダを基準としています。
ttscore/は判定エンジン(純粋な Python)、live/はリアルタイムワーカー、batch/は録画映像ワーカー、experiments/は実験コードです。 - 計測の生データと方法:リポジトリ
docs/tt/PERFORMANCE.md2.1·2.9.8、リアルタイムデモ設計書第 9 節、実験記録 E00(2026-10-13)。 - OpenTTGames: https://lab.osai.ai/ (CC BY-NC-SA 4.0)
- Extended OpenTTGames: https://arxiv.org/abs/2512.19327, https://github.com/moamal01/table_tennis_data (CC BY-NC-SA 4.0)
- BlurBall: https://arxiv.org/abs/2509.18387, https://github.com/cogsys-tuebingen/BlurBall (コード MIT)