備忘録

弱小院生のメモ

スコア部分の文字列切り出し

前回まででスコア表示部分のヘッダーが取れたので、その下のスコア表示部分を切り抜き、文字認識に繋げる

スコア表示部分切り抜き

  • ヘッダ検出結果から、その下部の領域を適当に切り出す
  • 欠けてしまうと文字認識が失敗するため、無駄な部分が入ろうとも大きめに切り出す方針

いい感じの切り抜き f:id:reverent_f:20170109154200p:plain

別部分も入った切り抜き f:id:reverent_f:20170109154205p:plain

2値化

文字位置特定や文字認識の処理を行うために2値化する。

対象画像の特性

  • 背景白に青色・縁取りありの数字が並ぶ
  • 切り抜きで余分な部分(青系統の色)が含まれる可能性が高い
  • ゲームセンターごとに環境光の影響で色味が変わる

試した2値化処理

  • 普通にcv2.THRESH_OTSUcv2.threshold()
    • 画像によって文字部分が欠けるなど安定しない
  • 適応的2値化処理cv2.adaptiveThreshold()
    • 同上
  • HSV変換→青色検出
    • 環境光の影響で安定せず
  • 白色検出→反転
    • 同上
  • (Bのみグレースケール) - (Gのみグレースケール) - (Rのみグレースケール)
    • うまくいきそうな気がしたけどダメ
  • 上記結果の組み合わせ(加算減算etc)
    • ダメなものを重ねてもダメ

最終的な2値化処理

画像のRのみ取り出してグレースケール化

 →大津の方法で2値化

が一番安定して文字部分を保持したまま2値化できた

red = img[:,:,2]
ret,bin_red = cv2.threshold(red,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

# オープニングで白色ノイズ除去
kernel = np.ones((3,3),np.uint8)
bin_red = cv2.morphologyEx(bin_red, cv2.MORPH_OPEN, kernel)

結果

こんな感じ

f:id:reverent_f:20170109155622p:plain

f:id:reverent_f:20170109155629p:plain

文字位置特定

2値化結果にノイズが乗っていた時期から色々試していたため、かなり苦労した。

試したこと

  1. 輪郭抽出

輪郭抽出 → 矩形に近似 → アスペクト比から文字候補検出

f:id:reverent_f:20170109160558p:plain f:id:reverent_f:20170109160602p:plain

問題点: - 2値化結果で1文字が2つの領域に分断されていると失敗

  1. ヒストグラムから判断

    X軸/Y軸ごとのヒストグラムを作成し、そこから文字位置を特定する

  2. Y軸のヒストグラムから文字が存在する範囲のyを特定・切り出し

  3. 切り出した部分に対してのX軸方向ヒストグラムを作成・文字位置特定

f:id:reverent_f:20170109161155p:plain f:id:reverent_f:20170109161158p:plain

文字以外の枠も検出されているが、仮にその後の文字認識処理においてこの部分が"1"と認識されたとしても、スコアの桁数が固定のため補正できると思う。

Tesseract-OCRを試したが認識率が安定しない。 学習データを集めてkNNで文字認識する。

あと横方向エッジ検出結果から画像の水平化もする必要がある