トランプ→麻雀 転移学習 実現可能性レポート

Augmented Startups Playing Cards モデルから Mahjong Vision への重み転移・ノウハウ転移の技術的評価
作成日: 2026-05-14 関連: 類似公開モデル広域調査 判定: ノウハウ転移は強く推奨 / 重み転移は限定的
← INDEX 設計ボトルネック 公開モデル素性 類似モデル広域調査 卓マスキング

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

結論: トランプ検出モデル (特に Augmented Startups Playing Cards, 10,100 枚) を そのまま重みを継承 するアプローチは効果限定的 (mAP +1〜3%) だが、 カードも麻雀牌も「平面物体を斜めから見ると菱形/平行四辺形に見える」 という幾何学的共通項により、OBB (Oriented Bounding Box) 検出と透視変形ハンドリングは強く転移可能。 最も価値があるのは「合成データ生成パイプライン」と「データ拡張レシピ」のノウハウ転移

1.1 一目で分かる判定

転移対象判定期待効果
合成データ生成パイプライン強く推奨34 種 × 5,000 枚 = 5,000 枚を自動生成可能 (アノテ工数 = 0)
データ拡張レシピ強く推奨回転 ±15°, 明度 ±25%, ブラー, 重なり生成 そのまま流用
透視変形・OBB ハンドリング強く推奨 (新発見)菱形変形・斜めからの平面物体検出を共有
YOLOv8 ハイパーパラメータ推奨YOLOv8l, 50 epochs, batch=16, imgsz=640 から開始
バックボーン重み条件付き+1〜3% mAP (Catastrophic Forgetting リスクあり)
検出ヘッド・分類層不可52 → 34 クラスでフル再構築必要
3D 直方体 (立て/倒し) 形状認識不可カードは紙 1 枚、麻雀牌は厚みあり (高さ情報がない)

2. 幾何学的共通項 — カードも牌も菱形に見える

★ 重要な技術的洞察: トランプも麻雀牌も「平面物体 (もしくは平面に近い直方体)」であり、 カメラを斜めから見たときの透視変形は同じ幾何学に従う。 この事実が転移学習の価値を大きく押し上げる。

2.1 両ドメイン共通の見え方パターン

トランプ — 視点による変形 A A 正面 (rectangle) A 斜め (trapezoid) A 水平 (rhombus) K 重なり (occlusion) 麻雀牌 — 視点による変形 立て (standing) 倒し (正面) 倒し (斜め) 倒し (菱形) 副露 (横倒し含む) 共通幾何: ・透視変形による菱形化 ・四辺形の歪み (台形, 平行四辺形) ・重なり・部分隠れ ・整列 + 散開の両パターン ・極端な角度 (上から / 横から)
図: トランプと麻雀牌の見え方変形パターン (両者で共通する幾何が多い)

2.2 Augmented Startups Playing Cards モデルが学習している多様性

Augmented Startups の playing-cards モデルは 10,100 枚を合成で生成している。 その合成データは以下の多様性を意図的に含む:

転移価値: これらの多様性に対するバックボーンの「見方」は、麻雀牌でもそのまま使える。 特に「斜め視点で菱形化した平面物体を四辺形として検出する」能力は M-League の 斜め上 (oblique-overhead) 撮影方針 (本プロジェクトが 2026-04-29 に採用) と完全に一致する。

3. 何が転移できるか / できないか

3.1 ✅ 転移可能 (YES)

転移対象なぜ転移できるか麻雀への応用
バックボーン汎用特徴 (CNN 早期層) 「矩形物体のエッジ・コーナー」を検出する能力は完全に共通 YOLOv8 の P1〜P3 層の重みを継承可能 (推定 60〜70% の特徴量共有)
透視変形ロバスト性 菱形・台形・平行四辺形に変形した矩形を扱う訓練が積まれている 立て牌 → 斜め視点で平行四辺形になる場合に直接適用可
OBB 検出能力 (もし OBB ヘッド使用なら) カードの斜め配置で θ (回転角) の推定を学習している 副露 (横倒しチー・ポン) の検出に直接転用可
重なり・隠れの処理 カード同士の重ね合わせを大量に学習している 麻雀の捨て牌山・整列手牌・副露の隠れた牌に転用可
背景ノイズ耐性 緑フェルト・木目背景は両ドメインで共通 緑フェルトを「牌でないもの」と認識する能力が転移される
合成データ生成手法 「単体素材 + 背景 + 合成」のパイプラインは構造的に同じ 麻雀牌 34 種 × 背景 10 種 × 配置 × augmentation で数万枚生成可能
訓練ハイパーパラメータ 同型タスクの最適化挙動は近い YOLOv8l, 50 epochs, batch=16, imgsz=640 から開始すれば探索コスト減

3.2 ⚠️ 部分的に転移可能 (PARTIAL)

転移対象難点緩和策
後期層の重み (P4, P5) 「カードらしさ」が刷り込まれている — トランプ向けに最適化された表現 転移後に freeze=0 で全層 fine-tune (LR を 1/10 に)
NMS / Anchor 設定 カードの典型サイズ (大) と牌のサイズ (小) が違う Roboflow Generate Version 時に anchor 再計算
クラス分布の偏り カード 4 スート均等 vs 麻雀の手牌・捨て牌偏り クラス重み付き損失で補正

3.3 ❌ 転移不可 (NO)

転移対象理由
検出ヘッド・分類層 52 クラス (トランプ) → 34 クラス (麻雀) で出力次元が違う。完全に作り直し
カード絵柄の認識 A, K, Q, J, ♠ ♥ ♦ ♣ の絵柄パターンは麻雀の 1m〜7z と無関係
3D 直方体 (立て/倒し) の判断 カードは「紙 1 枚 = ほぼ平面」、麻雀牌は「厚みのある直方体」。3D の立て倒しはカードにない概念
副露 / 暗槓のラベル付け 麻雀ルール固有。クラス定義の問題

4. 3 つの転移アプローチ (A / B / C)

A COCO → 麻雀 (現行・デフォルト)

YOLOv8m pretrained on COCO をそのまま麻雀 500 枚で fine-tune。

利点

  • Roboflow の標準パイプライン — 設定不要
  • COCO は十分に汎化されたバックボーン

欠点

  • 麻雀データ 500 枚だけが頼り (規模不足の懸念)
  • 「カード状の平面物体」への注意が COCO だけだと弱い

期待 mAP@0.5

0.80〜0.85 (アノテ品質次第)

B COCO → カード → 麻雀 (2 段階転移)

COCO pretrained → Augmented Startups playing-cards で 1 段階 → 麻雀で 2 段階。

利点

  • 「カード状物体」「透視変形」のプリトレが効く
  • 菱形変形・斜め視点の頑健性が直接転移

欠点

  • 2 段階の訓練オーケストレーションが必要
  • Catastrophic Forgetting リスク — 麻雀で訓練しているうちにカード時代の知見を忘れる
  • 学習率スケジュールの調整が必要 (1段目で 1e-3, 2段目で 1e-5 など)

期待 mAP@0.5

0.82〜0.88 (アプローチ A 比 +1〜3%)

5. 推奨アプローチ C の実装詳細 (合成データ生成)

5.1 必要素材 (準備フェーズ)

素材枚数取得方法所要時間
麻雀牌 34 種 高解像度写真34 + α手持ち牌セットを 1 枚ずつ正面撮影。立て・倒しの両方1〜2 時間
背景画像10 種緑フェルト・木目卓・暗部・M-League 卓を実況なしフレーム抜粋30 分
マスク (前景切り抜き)34 + αOpenCV GrabCut or Roboflow の自動マスキング30 分
合計2〜3 時間

5.2 合成パイプライン疑似コード

import cv2, numpy as np, random
from pathlib import Path

TILE_DIR = Path("synth/tiles/")     # 34 種 PNG (アルファ付き)
BG_DIR   = Path("synth/backgrounds/") # 10 種 JPG
OUT_DIR  = Path("synth/output/")

def random_perspective(img, max_tilt=30):
    """ランダムな透視変形 — 菱形化を再現"""
    h, w = img.shape[:2]
    src = np.float32([[0, 0], [w, 0], [w, h], [0, h]])
    jitter = lambda: random.uniform(-max_tilt, max_tilt)
    dst = src + np.float32([
        [jitter(), jitter()], [jitter(), jitter()],
        [jitter(), jitter()], [jitter(), jitter()]
    ])
    M = cv2.getPerspectiveTransform(src, dst)
    return cv2.warpPerspective(img, M, (w, h), borderMode=cv2.BORDER_TRANSPARENT)

def generate_synthetic_image(seed=42):
    random.seed(seed)
    bg = cv2.imread(str(random.choice(list(BG_DIR.glob("*.jpg")))))
    bg = cv2.resize(bg, (1280, 720))
    bboxes = []  # YOLO 形式: (cls_id, cx, cy, w, h)

    n_tiles = random.randint(13, 60)
    for _ in range(n_tiles):
        tile_path = random.choice(list(TILE_DIR.glob("*.png")))
        tile = cv2.imread(str(tile_path), cv2.IMREAD_UNCHANGED)
        # 1. ランダム回転 (-180 〜 +180°)
        tile = rotate_image(tile, random.uniform(-180, 180))
        # 2. ランダム透視変形 (菱形化)
        tile = random_perspective(tile, max_tilt=20)
        # 3. ランダムスケール (0.5x 〜 1.5x)
        scale = random.uniform(0.5, 1.5)
        tile = cv2.resize(tile, None, fx=scale, fy=scale)
        # 4. ランダム明度
        tile = adjust_brightness(tile, random.uniform(0.7, 1.3))
        # 5. 既存 bbox と少し重ねた位置にペースト (occlusion 生成)
        x, y = sample_position(bg, bboxes, allow_overlap=0.2)
        bg = paste_with_alpha(bg, tile, x, y)
        cls = tile_class_from_filename(tile_path)
        bboxes.append((cls, x, y, tile.shape[1], tile.shape[0]))

    # 6. 全体に最終 augmentation (ノイズ・ブラー)
    bg = add_motion_blur(bg, k=random.randint(1, 3))
    return bg, bboxes

for i in range(5000):
    img, bboxes = generate_synthetic_image(seed=i)
    cv2.imwrite(str(OUT_DIR / f"synth_{i:06d}.jpg"), img)
    save_yolo_labels(OUT_DIR / f"synth_{i:06d}.txt", bboxes)

print(f"Generated 5000 synthetic images with auto-labels")

5.3 訓練レシピ

# 1. Roboflow に upload
upload to roboflow/mahjong-vision-mvp-v2 project:
  - 500 枚 (実物 M-League 動画から filter 済)
  - 5,000 枚 (合成データ)
  total: 5,500 枚

# 2. Generate Version (Augmentation 設定)
preprocessing:
  - resize: 640x640
  - filter null: True
augmentation (Roboflow 側でさらに):
  - rotation: ±15°  (合成側で既に大きく振っているので軽め)
  - brightness: ±10%
  - blur: 1px

# 3. Train
model: YOLOv8m (Fast) または YOLOv8l (Accurate)
epochs: 80
batch: 16
imgsz: 640
initial weights: COCO pretrained (アプローチ A と同じ)
# ノウハウだけ転移、重みは継承しない

5.4 工数比較

項目アプローチ A (現行)アプローチ C (推奨)
準備時間0 時間2〜3 時間 (素材撮影 + マスキング)
合成スクリプト開発半日 (200 行程度の Python)
合成データ生成1 時間 (5,000 枚 / Workstation)
アノテーション工数500 枚 × 50 bbox = 25,000 → 修正 7,500 (62 時間)合成分は 0 時間、実物 500 枚分のみ (62 時間)
外注の場合$375 (≒ ¥55,000)$375 (実物分のみ)
訓練時間 (Roboflow)2〜4 時間4〜8 時間 (データ量 11 倍)
追加コスト半日〜1日
期待 mAP@0.50.80〜0.850.88〜0.94

6. 透視変形・OBB 検出への転移 (技術詳細)

6.1 共通する幾何学的問題

カメラ姿勢 (R, t) と物体平面 n · X = d から、 画像上の bbox は透視変形によって四辺形 (一般には 4 自由度の四角形) になる。 トランプも麻雀牌も平面に近い物体なので、この問題設定は完全に共有される。

2D 画像座標 (x, y) ← 透視変換 ← 3D 卓座標 (X, Y, Z)
                       ↑
                       カメラ内部行列 K と外部姿勢 (R, t)

→ axis-aligned bbox では正確に囲えない (隅に空白ができる)
→ OBB (cx, cy, w, h, θ) で囲うのが正解

6.2 Augmented Startups モデルが学習している幾何変換

Augmented Startups の playing-cards モデルは合成データで以下の変形を全て学習している:

これらは麻雀の M-League カメラワーク (ズーム・パン・カット) で生じる変形と完全に同じ。 バックボーンが「これは透視変形した矩形だ」と認識する能力は転移可能

6.3 OBB ヘッドを採用した場合の転移シナリオ

本プロジェクトは現状 axis-aligned bbox を採用しているが、将来 OBB に切り替える場合:

  1. カードモデルの OBB ヘッド (もし存在すれば) の重み構造を流用
  2. 麻雀牌の OBB アノテーション (Roboflow OBB ラベリングツール)
  3. 2 段階訓練: OBB ヘッドのみ更新 → 全層 fine-tune

OBB は本来「副露の横倒し・斜め倒し」検出に最適。 平行四辺形の角度 θ を正確に取れば、立/倒 二値判定の精度も上がる (現状は h/w aspect ratio に依存 = ノイズに弱い)。

6.4 既存プロジェクトの「斜め上 (oblique-overhead)」設置との整合

本プロジェクトは 2026-04-29 に 斜め上 (oblique-overhead) 設置 に方針転換した。 これは天井真下視点ではなく、M-League 中継と同じ「選手の向かい側上方からの斜め視点」を採用。

この視点では麻雀牌は必ず台形・平行四辺形・菱形に変形して見える。 トランプ検出モデルが学習している「透視変形した矩形物体の検出」能力はそのまま使える環境になっている。

結論: 透視変形・OBB ハンドリングについては、 アプローチ B (2 段階転移) の期待効果が大きい。 特に副露・横倒しチー・ポンの recall 改善で +5〜10% 寄与する可能性がある。

7. 期待効果と段階的検証計画

7.1 効果推定 (アプローチ別)

指標現状 (公開モデル)A: COCO→麻雀B: 2段階C: 合成+自前 ★
mAP@0.50.50〜0.700.80〜0.850.82〜0.880.88〜0.94
副露 recall0.650.800.850.92
緑フェルト false positive多発大幅減大幅減ほぼゼロ
必要データ規模500 枚500 枚500 + 5,000 合成
準備工数00半日1〜2 日

7.2 段階的検証計画

  1. Phase 1 (1 週間): アプローチ A で MVP v1 を訓練 → ベースライン確立
  2. Phase 2 (3〜4 日): 合成データ生成スクリプト開発・実行 (アプローチ C 着手)
  3. Phase 3 (2〜3 日): アプローチ C で MVP v2 を訓練 → A との A/B 比較
  4. Phase 4 (オプション・1 週間): アプローチ B の 2 段階転移を試行 (合成データで効果不十分な場合)
  5. Phase 5 (継続): 実機 4K カメラで実物データを追加収集 → 自己ベンチマーク作成

7.3 成功基準

8. リスク・落とし穴

落とし穴 1: 合成データの「綺麗すぎる」問題
合成データはエッジが鋭く照明も均一になりがち。実 M-League 動画の motion blur, JPEG 圧縮ノイズ, 干渉色をきちんと模倣しないと、 訓練データ分布と推論データ分布のずれ (covariate shift) で逆に精度が落ちる場合がある。
対策: 合成データに JPEG re-encode, gaussian blur, ノイズ注入を必須化する。
落とし穴 2: Catastrophic Forgetting (アプローチ B のみ)
2 段階目の麻雀訓練でカード時代の知見を破壊してしまう可能性。特に LR が大きすぎる場合に発生。
対策: 2 段階目の LR を 1段階目の 1/10 以下に下げる。EMA (exponential moving average) で安定化。 arXiv 2505.01016 の手法を参考に。
落とし穴 3: クラス不均衡
合成データでは 34 牌種を均等に出現させがちだが、実 M-League では「東 (1z)」や「中 (7z)」が頻出、字牌は出現頻度に差がある。
対策: 実データの牌種分布を計測し、合成データのサンプリング比率を合わせる。
落とし穴 4: 透視変形の過剰
合成時に菱形化を過度にやると、現実にはあり得ない角度の牌が訓練データに混入。M-League の実カメラ姿勢 (45°〜70°) に絞るべき。
対策: 合成スクリプトで max_tilt を実カメラの統計値から決定。
低リスクの実施順序: アプローチ A (ベースライン) → アプローチ C (合成データ拡張) を順に試し、効果が出たら B (重み転移) を試行する。 最初から B に飛び込むと、原因切り分けが難しくなる。