← 投稿一覧

OCRでりんごゲームの盤面を抽出する

問題: 実際の盤面データが必要だった

りんごゲームの盤面がどのように生成されているかを研究するには、まず実際の盤面データが必要でした。それも大量に。しかしゲーム自体には盤面を構成する数字をエクスポートする機能がありません。問い合わせるAPIも、解析するセーブファイルもありません。画面に見えるものがすべてです--緑の枠の中に並ぶ一桁の数字のグリッドです。

つまり、スクリーンショットから直接数字を抽出するしかありませんでした。意味のある統計分析には数枚の盤面では不十分で、数百枚が必要でした。手作業ではとても対応できない量です。

りんごゲームの盤面スクリーンショットりんごゲームの盤面スクリーンショット

OCRが唯一の手段だった理由

研究には最低500枚の盤面が必要でした。18セルのグリッドをスクリーンショットから手動で読み取るには、1枚あたり1~2分かかります。500枚となると、16時間以上の単調で間違いやすい作業になります。たった1つの数字の読み間違いが、後続の分析全体を汚染しかねません。

自動化されたパイプラインが唯一の現実的な方法でした。OCRならスクリーンショット1枚を1秒未満で処理でき、500枚全体でも数分で完了します。さらに重要なのは、決定的なパイプラインは一貫した結果を生み出すということです。同じスクリーンショットは常に同じ出力を生み、人間のミスによるブレがありません。

抽出パイプライン

パイプラインは生のスクリーンショットを受け取り、18個の整数の配列を出力します。5つのステージで動作します:

  1. フレーム検出。りんごゲームの盤面は特徴的な緑の枠の中にあります。HSV色空間での色閾値処理でこの枠を検出し、最大の輪郭を見つけてスクリーンショット内の盤面領域を正確に特定します。
  2. 盤面のクロップ。緑の枠の位置が分かったら、盤面部分だけを切り出します。スコア表示、背景、UIの装飾はすべて除去されます。
  3. グリッド整列。盤面は固定の3×6グリッド(3列・6行)です。盤面の寸法から行と列の境界を計算し、18個の等しいセルに分割します。
  4. セルの分離。18個のセルそれぞれを個別のサブイメージとして抽出します。この時点で各画像には数字が1つだけ含まれています。
  5. OCR。各セル画像を前処理し、Tesseractで数字を認識します。
緑の枠で検出された盤面領域緑の枠で検出された盤面領域18セルのグリッド整列オーバーレイ18セルのグリッド整列オーバーレイ

前処理: OCRの精度を高める

生のセル画像はそのままではOCRに適していません。数字はコントラストの異なるカラー背景の上にあり、セル画像自体も小さいです。前処理なしでは、Tesseractが数字を誤読したり、結果を返さないことが頻繁にありました。

各セルは6段階の前処理を経ます:

  1. 余白のクロップ。四辺から小さな余白を切り落とします。グリッド線や隣接セルの残りを除去するためです。
  2. グレースケール変換。RGBから単一チャネルのグレースケールに変換し、ノイズを減らし入力を単純化します。
  3. 二値化。大津の適応的閾値処理で画像を二値化します。数字が背景からくっきり分離した白黒画像が生成されます。
  4. 反転。Tesseractは明るい背景に暗い文字を期待します。ゲームの配色に応じて画像を反転し、数字が常に白背景に黒になるようにします。
  5. パディングとリサイズ。数字の周りに均一な白い余白を追加し、画像を拡大します。小さな画像はOCR失敗の最も一般的な原因です。
  6. 数字専用のTesseract設定。最初は--psm 10(単一文字モード)を試しましたが、実際には認識精度が不安定でした。--psm 6(均一なテキストブロック)に切り替えたところ、精度が大幅に向上しました。文字ホワイトリストを1~9の数字に制限し、エンジンが文字や特殊文字を推測するのを防ぎます。
OCR前処理のステップOCR前処理のステップ

各セルはCrop、Grayscale、Threshold、Inversion、Paddingのステップを経てOCRに入力される。

検証

りんごゲームの盤面にはルールがあります。すべての数字の合計は必ず10の倍数でなければなりません。

i=1170di0(mod10)

これが無料のChecksumになります。OCRが1つでも間違えれば、偶然通過する確率は約10分の1。500枚全て通過しました。

Checksumだけでは完璧ではありません。エラーが相殺すれば合計は通過し得ます。そのため25枚(5%)を4,250個の数字を手動で照合。エラー0件。

Rule of Threeを適用すると:

p3n=325=0.12

Checksumと組み合わせると:

Pundetected=0.12×0.1=0.012

厳密に言えば、2つの検証方法が独立であることをまず証明する必要があるが、独立と仮定すれば、未検出エラーの結合確率は1.2%である。実際のエラー率は0かそれに非常に近いと考えています。500枚ですり抜けたものはありませんでした。

500枚の盤面の分析結果は、AppleGame+盤面生成の完全な研究でご覧いただけます。

投稿一覧