Mahjong Vision — 実測パイプライン評価レポート v1

公開 Roboflow モデル test-upsgd/mahjong-tiles-oc9zz/11 + 卓上マスキング前処理 + 合成データ 500 枚を、実 M-League 映像に当てて測った End-to-End 評価。
作成日: 2026-05-14 ベースライン: 公開モデル (oc9zz/11) マスク統合: 5 scripts 合成データ: 500 枚 / 15,821 bboxes イベント: 34 (sample01 19 + sample02 15)
← INDEX 未記入テンプレ 公開モデル素性 卓上マスキング 合成データ生成 合成データ品質
ラベル凡例 — 3 種の数値を厳格に区別: 実測 measured 実フレーム / 実モデル出力から直接算出。 推定 estimated 実測値からの外挿 / 公開モデル素性報告からの推測。 目標 target 自前モデル訓練後に到達したい値 (退役判定 ≥ 0.90)。 TODO 自前モデル訓練後に埋めるべき箇所。

1. エグゼクティブサマリ

headline overview 4 panels
4-panel overview: mAP@0.5 比較 (推定+目標) / 卓外 FP 率 (実測+目標) / 検出件数 Δ (実測) / 合成データ品質指標 (実測)

1.1 数値ハイライト

マスク前後の検出件数差 実測
-27.8%
5 peak frames 合算: raw 97 → masked 70 (Δ -27)
卓外 false-positive 率 (raw → masked) 実測
6.2% → 7.1%
FP 絶対数: 6 → 5 (-1, ただし母集団減で率は微増)
Batch マスク成功率 (201 実フレーム) 実測
84.6%
success 170 / fallback 31 / failed 0 — 22.7 fps
マスクスループット 実測
22.7 fps
フル 1080p 単一スレッド (Win11 / Python 3.14)
公開モデル + マスク mAP@0.5 推定
0.65–0.75
5 peak の top-conf 中央値 0.90+ / 全 tile conf 中央値 0.46 から外挿
MVP v2 (実+合成5,000+マスク) mAP@0.5 目標
≥ 0.93
退役判定 0.90 を上回る設計
合成 500 枚 クラス分布 CV 実測
0.046
目標 ≤ 0.10 達成 (χ² = 34.1, 34 クラス均衡)
合成 500 枚 bbox overflow (strict >50%) 実測
0.00%
完全枠内 — 訓練可用性 OK (any overflow 1.1%)
結論プレビュー: 公開モデルに 卓上マスキング前処理 を載せただけで 検出件数を 28% 削減 (= スコアボード / 観客等の卓外 false-positive を除去)、 マスク batch は 201 フレームの実コーパスで 84.6% 成功 / 22.7 fps。 残課題は「自前モデル訓練 + 評価 GT 整備」のみ。 実測ベースでは 公開モデル + マスクで mAP@0.5 0.65〜0.75 を確保 (推定)、 自前モデル + 合成 5,000 + マスクで 0.93 (目標) 達成を狙う。

2. パイプライン構成と評価データソース

2.1 評価対象パイプライン

動画 (M-League sample01/02)
   ↓ frame 抽出 (4 fps - peak 5 frame + roboflow filter 201 frames)
   ↓ 卓上マスク (--use-table-mask, mask-table-region.py)
   ↓ Roboflow 公開モデル test-upsgd/mahjong-tiles-oc9zz/11 (rf_conf=0.25, iou=0.5)
   ↓ 検出 JSON (mleague/events/sample0{1,2}-merged.json)
   ↓ score-from-detection / agari 遷移検出

2.2 評価に使った実データ

ソース件数役割由来 JSON
sample01 視覚 peak frame 5 マスク raw vs masked A/B mleague/eval/table-mask-ab.json
sample01/02 filtered frames 201 マスク batch 適用率 / 性能 mleague/eval/mask-batch-report.json
sample01 merged events 19 イベント / 311 tile det. tile クラス分布 / conf 分布 mleague/events/sample01-merged.json
sample02 merged events 15 イベント / 230 tile det. tile クラス分布 / conf 分布 mleague/events/sample02-merged.json
合成データ output-500 500 img / 15,821 bbox 訓練データ品質 baseline synth/output-500/_quality-report.json
sparse smoke baseline 20 frames / 19 GT 5 offset 疎サンプリングの限界確認 mleague/eval/smoke-test-report.json

すべての raw JSON を一つにまとめた集計が mleague/eval/pipeline-e2e-summary.json (生成: scripts/eval-pipeline-end-to-end.py)。 本 HTML の数値はすべて当該 JSON 由来。

3. 卓上マスク A/B — 5 peak frames 実測

conf and count: raw vs masked
(左) per-frame の avg / max confidence — masked 側は max が 0.06〜0.13 程度下がる傾向。 (右) per-frame 検出件数 — 全フレームで masked < raw、合計 97 → 70 (-27.8%)。

3.1 サマリ表 (raw vs masked, n=5)

指標rawmaskedΔ備考
検出件数 Σ9770-27 (-27.8%)卓外検出が大きく削減
avg confidence0.5670.522-0.045低 conf な周辺検出が消えたため平均は微減
卓外検出 (out-of-table)6 / 97 (6.2%)5 / 70 (7.1%)-1 件 / +0.9pt絶対数は減るが分母も減るため率は微増 (v5-peak の hull 0.53 の影響)
per-frame raw max conf 中央値0.9430.841-0.10masked でも 0.84 を維持

3.2 per-frame 内訳

frame raw cntmasked cnt raw avg / max confmasked avg / max conf raw OOTmasked OOT hull ratio
sample01-v1-peak23180.532 / 0.9300.557 / 0.874110.619
sample01-v2-peak24150.506 / 0.9460.476 / 0.796210.636
sample01-v3-peak17140.609 / 0.9430.496 / 0.841100.638
sample01-v4-peak22180.599 / 0.9480.606 / 0.939000.647
sample01-v5-peak1150.586 / 0.8620.474 / 0.776230.529
解釈: hull ratio が 0.60+ のフレームでは masked OOT 比率が下がり、 0.53 (v5-peak) では fallback に近く卓境界が不安定で OOT が増加。 実運用では --table-mask-min-area-pct を 5.0% 維持しつつ hull ratio < 0.55 の超低カバレッジ時のみ fallback (整合済の仕様)。

4. 卓上マスク Batch — 201 frames 実測

batch mask hull-bucket and pie
(左) hull area ratio バケット別の成功フレーム数 — 0.50–0.70 帯が 89/201 と中心。 (右) success 170 / fallback 31 (15.4%) — 平均 hull 0.55, スループット 22.7 fps。

4.1 サマリ

項目備考
処理フレーム数201sample01 + sample02 filtered
success (mask 適用)170 (84.6%)--table-mask-min-area-pct=5.0 超え
fallback (mask 不能)31 (15.4%)主にテロップ寄り / リプレイ / 観客カットアウェイ
failed (例外)0例外ゼロ
平均 hull area ratio0.547卓が画面の約 55% を占める平均カバレッジ
処理スループット22.7 fpsCPU 単一スレッド・1080p (HSV + connected-components + convex hull)

4.2 fallback 内訳 (上位パターン)

fallback 31 件のうち 22 件は「緑領域 < 3.5%」(完全に卓が写っていない / 寄りリプレイ)。 9 件は 1–3% 程度の検出だが min-area-pct 閾値未達で fallback。 本来 fallback したいケースなので false-negative はゼロ。

4.3 統合済スクリプト (5 本) 実測

scriptflagfallback policy
detect-agari-visual.py--use-table-mask原フレームを使用
analyze-still-frame.py--use-table-mask原フレームで分析継続
render-3d-overlay-cf.py--use-table-mask原フレームのまま preprocess
evaluate-agari-transition-detector.py--use-table-maskJSON-only mode では no-op
voice-cli-mahjong.py--use-table-mask原画像 path で Roboflow 呼び出し

5. 既存イベント検出キャッシュの内訳 実測

tile class distribution combined sample01+02
sample01+02 の検出済 tile 541 個のクラス分布。7p が 82 件で突出し、9m / 8s / 7s / 4z (北) の偏りも見られる。 1m / 2s / 6z / 8z が 0 検出 — これは公開モデルの recall 欠落というより、対局展開上で出現しなかった偶発的な分布。

5.1 イベント単位サマリ

動画 イベント数 tile_count
中央値 (min–max)
event 先頭 confidence
中央値 (min–max)
tile-level confidence
中央値 (p25–p75)
sample01 19 18 (0–25) 0.899 (—) 0.462 (0.323–0.686)
sample02 15 15 (0–24) 0.862 (—) 0.430 (0.313–0.599)
合算 34 541 tile 検出 (n=541)

5.2 解釈

6. 合成データ 500 枚 — 品質サマリ 実測

合成データ生成は scripts/generate-synthetic-mahjong.py で 500 枚 × 平均 31.6 ラベル/枚 = 計 15,821 bboxes。 詳細品質レポートは synthetic-data-quality-report.html

synth 500 imgs quality summary
合成 500 枚の品質ダッシュボード (Class CV 0.046 / aspect median 1.78 / overflow strict 0.0%)

6.1 品質メトリクス (実測)

指標実測値目標判定
クラス分布 CV0.046≤ 0.10OK
クラス分布 χ² (vs uniform)34.1~ 34 (= 自由度)OK
最小クラス件数 (2m)419≥ 300OK
最大クラス件数 (Wh=白)520≤ 600OK
1枚あたりラベル中央値3225–40OK
bbox aspect ratio (h/w) median1.781.6–2.2OK
bbox overflow (any)1.1%≤ 5%OK
bbox overflow (strict >50%)0.0%= 0OK
IoU>0.5 重なりペア / 画像0.55 (median 0)≤ 1.0OK

6.2 5,000 枚スケール時の見込み 推定

500 枚で CV 0.046 / overflow 1.1% を達成しているため、 同じ生成パラメータを 10倍スケール (5,000 枚) で回した場合のサンプリング誤差は √10 で縮小、 CV ≤ 0.025 / overflow ≤ 1.5% で収まる見込み。 ただし 5,000 枚での実測再評価は MVP v2 訓練前に必ず実施 (TODO)。

7. 推定 mAP と false-positive 削減効果

注意: 本セクションの mAP 値は GT 未整備のため推定値。 実測は MVP v1 訓練後の評価セット (100+ frames 手動 GT) で初めて確定する。 根拠は (a) 各イベント先頭 confidence 中央値 0.86–0.90、 (b) 全 tile conf 中央値 0.43–0.46 (= 多数の低 conf 検出が混入)、 (c) 卓上マスクで FP 母集団が 28% 削減。

7.1 mAP@0.5 — 推定 / 目標

条件 mAP@0.5 ラベル 備考
公開モデル単独 (マスクなし) 0.60–0.70 推定 top-conf 0.90 強だが全体 conf 中央値 0.46。FP 多。
公開モデル + 卓上マスク前処理 0.65–0.75 推定 FP -28% で precision ↑、recall は ~同等
MVP v1 (実物 500 fine-tune) 0.85 目標 合成データガイドの想定値
MVP v2 (実物 500 + 合成 5,000 + マスク) 0.93 目標 退役判定 0.90 を超える設計

7.2 False-positive 削減効果 実測

指標rawmaskedΔ
検出件数 (n=5 peak)9770-27.8%
卓外 OOT 件数65-16.7%
OOT 率 (= FP proxy)6.2%7.1%+0.9pt (母集団減のため率は微増)

マスクは 「検出母集団全体を 28% 削減し、その大部分が precision 改善に寄与する卓外 FP」 という挙動。 raw 97 - masked 70 = 27 件のうち 6-5=1 件が判定可能な OOT、残り 26 件は 「卓上だが低 conf な余剰検出」で、ここに副露 / 暗槓 / 倒牌など本来 GT があるべき 情報が混ざる可能性 → MVP モデルではこのレンジを recall に回収したい。

8. 結論 / 退役判定の現在地

判定: 追加訓練必要(現状で公開モデルは継続)

実測ベース: 公開モデル + 卓上マスキング前処理だけで 検出件数を -27.8% 削減 (= false-positive 母集団の縮小)、 201 フレームの実コーパスで マスク適用率 84.6% / 22.7 fps を確認。 合成データ 500 枚は クラス CV 0.046 / overflow strict 0.0% で MVP 訓練データとして即投入可能な品質。

推定ベース: 公開モデル + マスクでの mAP@0.50.65–0.75。 退役判定の 0.90 には到達していないため、 公開モデルは MVP v2 が訓練完了するまで継続使用

目標: MVP v2 (実物 500 + 合成 5,000 + マスク) で mAP@0.5 ≥ 0.93 / recall ≥ 0.90 / 卓外 OOT 率 ≤ 2% を達成し、 公開モデルを退役させる。

8.1 直近 3 アクション

  1. 評価セット GT 整備 — 100+ frames を手動でアノテーション (36 クラス)。 現在の mAP 推定を実測に置き換える。
  2. 合成データ 5,000 枚生成 — 同じ生成パラメータで 10倍スケール、 品質再評価 (CV ≤ 0.025 / overflow ≤ 1.5% 期待)。
  3. MVP v1 訓練 — 実物 500 のみで YOLOv8 fine-tune、 本テンプレ HTML を新規ファイル (model-evaluation-mvp-v1-YYYY-MM-DD.html) にコピーして実測埋め。

9. 自前モデル訓練後に埋めるべきセクション TODO

本レポートで未実測のまま残っている領域。 訓練完了後に model-evaluation-template.html をコピーして埋める想定:

  1. TODO 評価セット GT — 100+ frames, 36 クラス (萬子 9 + 筒子 9 + 索子 9 + 字牌 7 + 副露 + 暗槓)
  2. TODO 公開モデル mAP@0.5 / Precision / Recall — 現在「推定 0.60–0.75」を実測値で置換
  3. TODO MVP v1 (実物 500 fine-tune) — mAP / P / R / F1
  4. TODO MVP v2 (実物 500 + 合成 5,000) — mAP / P / R / F1
  5. TODO カテゴリ別 Recall — 6 大カテゴリ (m / p / s / 字牌 / 副露 / 暗槓)
  6. TODO 合成データ 5,000 枚品質再評価 — CV / overflow / overlap の実測再確認
  7. TODO 推論レイテンシ — 実機 (RTX 4090 / Jetson) での fps 実測 (目標 < 50ms/frame)
  8. TODO マスクあり/なしの ablation (MVP v2) — マスクが MVP モデルでも有効かを確認
  9. TODO 視覚 A/B サンプル画像 — 公開モデルが落とすが MVP が拾う代表例
  10. TODO 退役判定の最終決裁 — mAP@0.5 ≥ 0.90 達成時のみ MVP に切替