スコア部分の文字列切り出し
前回まででスコア表示部分のヘッダーが取れたので、その下のスコア表示部分を切り抜き、文字認識に繋げる
スコア表示部分切り抜き
- ヘッダ検出結果から、その下部の領域を適当に切り出す
- 欠けてしまうと文字認識が失敗するため、無駄な部分が入ろうとも大きめに切り出す方針
いい感じの切り抜き
別部分も入った切り抜き
2値化
文字位置特定や文字認識の処理を行うために2値化する。
対象画像の特性
- 背景白に青色・縁取りありの数字が並ぶ
- 切り抜きで余分な部分(青系統の色)が含まれる可能性が高い
- ゲームセンターごとに環境光の影響で色味が変わる
試した2値化処理
- 普通に
cv2.THRESH_OTSU
でcv2.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)
結果
こんな感じ
文字位置特定
2値化結果にノイズが乗っていた時期から色々試していたため、かなり苦労した。
試したこと
- 輪郭抽出
問題点: - 2値化結果で1文字が2つの領域に分断されていると失敗
ヒストグラムから判断
X軸/Y軸ごとのヒストグラムを作成し、そこから文字位置を特定する
Y軸のヒストグラムから文字が存在する範囲のyを特定・切り出し
- 切り出した部分に対してのX軸方向ヒストグラムを作成・文字位置特定
文字以外の枠も検出されているが、仮にその後の文字認識処理においてこの部分が"1"と認識されたとしても、スコアの桁数が固定のため補正できると思う。
次
Tesseract-OCRを試したが認識率が安定しない。 学習データを集めてkNNで文字認識する。
あと横方向エッジ検出結果から画像の水平化もする必要がある