test-upsgd/mahjong-tiles-oc9zz/11 + 卓上マスキング前処理 + 合成データ 500 枚を、実 M-League 映像に当てて測った End-to-End 評価。
mAP@0.5 推定mAP@0.5 目標動画 (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 遷移検出
| ソース | 件数 | 役割 | 由来 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 由来。
| 指標 | raw | masked | Δ | 備考 |
|---|---|---|---|---|
| 検出件数 Σ | 97 | 70 | -27 (-27.8%) | 卓外検出が大きく削減 |
| avg confidence | 0.567 | 0.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.943 | 0.841 | -0.10 | masked でも 0.84 を維持 |
| frame | raw cnt | masked cnt | raw avg / max conf | masked avg / max conf | raw OOT | masked OOT | hull ratio |
|---|---|---|---|---|---|---|---|
| sample01-v1-peak | 23 | 18 | 0.532 / 0.930 | 0.557 / 0.874 | 1 | 1 | 0.619 |
| sample01-v2-peak | 24 | 15 | 0.506 / 0.946 | 0.476 / 0.796 | 2 | 1 | 0.636 |
| sample01-v3-peak | 17 | 14 | 0.609 / 0.943 | 0.496 / 0.841 | 1 | 0 | 0.638 |
| sample01-v4-peak | 22 | 18 | 0.599 / 0.948 | 0.606 / 0.939 | 0 | 0 | 0.647 |
| sample01-v5-peak | 11 | 5 | 0.586 / 0.862 | 0.474 / 0.776 | 2 | 3 | 0.529 |
--table-mask-min-area-pct を 5.0% 維持しつつ
hull ratio < 0.55 の超低カバレッジ時のみ fallback (整合済の仕様)。
| 項目 | 値 | 備考 |
|---|---|---|
| 処理フレーム数 | 201 | sample01 + sample02 filtered |
| success (mask 適用) | 170 (84.6%) | --table-mask-min-area-pct=5.0 超え |
| fallback (mask 不能) | 31 (15.4%) | 主にテロップ寄り / リプレイ / 観客カットアウェイ |
| failed (例外) | 0 | 例外ゼロ |
| 平均 hull area ratio | 0.547 | 卓が画面の約 55% を占める平均カバレッジ |
| 処理スループット | 22.7 fps | CPU 単一スレッド・1080p (HSV + connected-components + convex hull) |
fallback 31 件のうち 22 件は「緑領域 < 3.5%」(完全に卓が写っていない / 寄りリプレイ)。
9 件は 1–3% 程度の検出だが min-area-pct 閾値未達で fallback。
本来 fallback したいケースなので false-negative はゼロ。
| script | flag | fallback 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-mask | JSON-only mode では no-op |
voice-cli-mahjong.py | --use-table-mask | 原画像 path で Roboflow 呼び出し |
| 動画 | イベント数 | 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) |
合成データ生成は scripts/generate-synthetic-mahjong.py で 500 枚 × 平均 31.6 ラベル/枚 = 計 15,821 bboxes。
詳細品質レポートは synthetic-data-quality-report.html。
| 指標 | 実測値 | 目標 | 判定 |
|---|---|---|---|
| クラス分布 CV | 0.046 | ≤ 0.10 | OK |
| クラス分布 χ² (vs uniform) | 34.1 | ~ 34 (= 自由度) | OK |
| 最小クラス件数 (2m) | 419 | ≥ 300 | OK |
| 最大クラス件数 (Wh=白) | 520 | ≤ 600 | OK |
| 1枚あたりラベル中央値 | 32 | 25–40 | OK |
| bbox aspect ratio (h/w) median | 1.78 | 1.6–2.2 | OK |
| bbox overflow (any) | 1.1% | ≤ 5% | OK |
| bbox overflow (strict >50%) | 0.0% | = 0 | OK |
| IoU>0.5 重なりペア / 画像 | 0.55 (median 0) | ≤ 1.0 | OK |
500 枚で CV 0.046 / overflow 1.1% を達成しているため、 同じ生成パラメータを 10倍スケール (5,000 枚) で回した場合のサンプリング誤差は √10 で縮小、 CV ≤ 0.025 / overflow ≤ 1.5% で収まる見込み。 ただし 5,000 枚での実測再評価は MVP v2 訓練前に必ず実施 (TODO)。
| 条件 | 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 を超える設計 |
| 指標 | raw | masked | Δ |
|---|---|---|---|
| 検出件数 (n=5 peak) | 97 | 70 | -27.8% |
| 卓外 OOT 件数 | 6 | 5 | -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 に回収したい。
実測ベース: 公開モデル + 卓上マスキング前処理だけで 検出件数を -27.8% 削減 (= false-positive 母集団の縮小)、 201 フレームの実コーパスで マスク適用率 84.6% / 22.7 fps を確認。 合成データ 500 枚は クラス CV 0.046 / overflow strict 0.0% で MVP 訓練データとして即投入可能な品質。
推定ベース: 公開モデル + マスクでの mAP@0.5 は 0.65–0.75。
退役判定の 0.90 には到達していないため、
公開モデルは MVP v2 が訓練完了するまで継続使用。
目標: MVP v2 (実物 500 + 合成 5,000 + マスク) で mAP@0.5 ≥ 0.93 / recall ≥ 0.90 / 卓外 OOT 率 ≤ 2% を達成し、 公開モデルを退役させる。
model-evaluation-mvp-v1-YYYY-MM-DD.html) にコピーして実測埋め。本レポートで未実測のまま残っている領域。 訓練完了後に model-evaluation-template.html をコピーして埋める想定: