【画像認識】画面抽出における背景除去と対象位置の特定【ポケモン対戦画面抽出】

# 1．記事の概要
本記事は下記画像認識に関連するものである。
記載している内容についてはweb上での使用を想定しているためjavascriptを使用した。

<div class="blog-card" style="padding:12px;margin:15px 0;border:1px solid #ddd;word-wrap:break-word;max-width:474px;width:auto;border-radius:5px;"><div class="blog-card-thumbnail" style="float:left;"><a href="http://qiita.com/ararabo/items/30080bcdcb4426ec0f77" class="blog-card-thumbnail-link" target="_blank"><img src="http://capture.heartrails.com/120x120/shorten?http://qiita.com/ararabo/items/30080bcdcb4426ec0f77" class="blog-card-thumb-image wp-post-image" alt="12436288584_94d6bc46d2_b.jpg" style="width:100px;height:100px;"></a></div><div class="blog-card-content" style="margin-left:110px;line-height:120%;"><div class="blog-card-title" style="margin-bottom:5px;"><a href="http://qiita.com/ararabo/items/30080bcdcb4426ec0f77" class="blog-card-title-link" style="font-weight:bold;text-decoration:none;color:#111;" target="_blank">【画像認識】ポケモン対戦画面抽出システムの概要と課題 - Qiita</a></div><div class="blog-card-excerpt" style="color:#333;font-size:90%;">xxxxxxxxxx</div></div><div class="blog-card-footer" style="font-size:70%;color:#777;margin-top:10px;clear:both;"><span class="blog-card-hatena"><a href="http://b.hatena.ne.jp/entry/http://qiita.com/ararabo/items/30080bcdcb4426ec0f77" target="_blank"><img border="0" src="http://b.hatena.ne.jp/entry/image/http://qiita.com/ararabo/items/30080bcdcb4426ec0f77" border="0" alt="" /></a></span></div></div>

#2.ポケモン対戦画像からアイコン位置を特定する
課題については上記記事にて記載しているとおり、
ポケモンの対戦画面からポケモンのアイコンを抽出する際、
背景色が存在するとRGBなどの色による特徴量を用いた場合、
背景色と同じ色の要素を持つポケモンのアイコンがマッチングしてしまう。

例えば以下の画像に対してテンプレートマッチングを行った場合、
![adfadfa.JPG](https://qiita-image-store.s3.amazonaws.com/0/135302/bfd5fd06-9d06-2366-da34-4be37479385e.jpeg)
中央付近の緑の部分にて、アイコンが緑色のポケモンとのマッチング結果が高くなってしまう。
例えば、キャタピーなどがあげられる。
![image_10.png](https://qiita-image-store.s3.amazonaws.com/0/135302/a8f7e2fb-6574-9503-a07f-d9c4691963c9.png)
キャタピーは自身の色が背景色に似ていることに加えて、
サイズが小さいことで、テンプレートマッチングにおいて
モデル画像をスライドさせて調べる回数が多く、領域を細かく調べるため
色が似ている背景色のみの領域で特徴量が高くなってしまう。
![adfadfa - コピー.JPG](https://qiita-image-store.s3.amazonaws.com/0/135302/fcc184a4-503b-ecbd-06b1-63d89516b827.jpeg)

この課題に対しては以下の解決方法がある
1. 背景色の除去
2. 背景色の多い領域の探索禁止

## 背景色の除去
背景色の除去方法についてはいろいろある。
例えば、動画を対象としているのであれば、
フレームごとに変化しているピクセルを判定して動いていない部分を
背景とする方法がある(前景処理)。

今回の場合、対象は静画であるため、上記は使えない。
静画についての背景の除去方法として
- HSV空間上での色除去
- レイヤー処理による色除去
を考えた

### HSV空間上での色除去
HSVは色相(Hue)、彩度(Saturation)、輝度(Value)から構成される色空間である。
![Hsv_sample.png](https://qiita-image-store.s3.amazonaws.com/0/135302/c01c70e7-0745-e02c-9a4d-5e1a4569f17c.png)

本来画像を取り込んだ際、RGB空間上で処理するが、
色を抜き取る際はこちらのほうが使い勝手が良いと考えた。

RGB空間で取り込んだ画像をHSV空間上に変換し、
あるHSV範囲のピクセルをすべて黒色に変換した画像は以下の通り。
![HSV処理.PNG](https://qiita-image-store.s3.amazonaws.com/0/135302/d6ce6a22-b9fc-3965-cddf-38fb11fd9e99.png)
これにより背景色である緑色を除去でき、テンプレートマッチングしやすいものとなる。

問題点としてアイコン画像で背景色と同じ緑色を使用している場合
アイコン画像部分がボロボロになり、判定できない。
![名前があると切り取りが上手くできない.png](https://qiita-image-store.s3.amazonaws.com/0/135302/a586fe73-be14-3f47-2b74-7eccc7941b42.png)

ここで左上のアイコン画像(サーナイト)が緑色を含んいたため、
画像としてはボロボロとなってしまった。
![image_282.png](https://qiita-image-store.s3.amazonaws.com/0/135302/81884939-4825-68ce-69f2-867cd23519eb.png)

### レイヤー処理による色除去
次に微粒取り出しによる背景除去を考えた
詳しい説明は[GIMPのレイヤー処理](https://docs.gimp.org/ja/gimp-concepts-layer-modes.html)を参考にしてほしい。
>微粒取り出し モードはレイヤーから「フィルム粒子」を抽出して純粒子からなる新たなレイヤーを生成するものらしいのですが、 エンボス加工を施したような画像にする目的にも適います。 上側のレイヤーの画素の値を下側のレイヤーの同じ位置の画素の値から引き、 128 を加えます。
等式はつぎのとおり。
式8.13 レイヤーモード「微粒取り出し」の等式
E=I-M+128
(ある画素の色 E 、上に重ねたマスクのその位置の画素の色 M 、同じ位置の下側にあるレイヤーの画素の色 I )

この微粒取り出し処理により背景を単一色にすることでここからHSV除去により先ほどよりはきれいに背景色を
抜くことができると考えた
![微粒取り出し.PNG](https://qiita-image-store.s3.amazonaws.com/0/135302/bbf68480-fabd-5208-9f14-3ec7b7cbc1b9.png)

ただしHSVによる背景色除去と同じように背景と同じ色のポケモンには対応できない

## 背景色の多い領域の探索禁止
背景色のみの領域を探索しなければ軽減されると考え、
以下の方法を試行した。
- 画像の分割
- 探索領域の推定

### 画像の分割
パーティを組めるポケモンの最大数6によって分割した。
これによって背景色が多い部分を調べなくてよい。
![6bunnkatu.jpg](https://qiita-image-store.s3.amazonaws.com/0/135302/dcee6fd3-00e4-e624-fe4f-09b6605f6bbe.jpeg)
しかしながら、この場合においても、サイズの小さいアイコンのポケモンがあると
そのポケモンの領域を調べる際に、背景色と同じ色のアイコンが選ばれやすくなってしまう。

### 探索領域の推定
6分割した場合、領域を制限することで探索部分を少なくすることができた。
しかしながらそれでも背景色が多くを占める部分については問題がある。

そこで、アイコンがある部分を直接見つける方法を考えた。
ポケモン対戦画面において、アイコンの下には必ずレベル表記がある。
またレーティングバトルにおいて、ポケモンのレベルはほぼ50が主流である。
そのため、下記のレベル画像をまず探索することを考えた。
![image_0.png](https://qiita-image-store.s3.amazonaws.com/0/135302/bfac5482-6281-6549-ec4f-815f5302608b.png)
探索した結果がこの画像である
![LV場所特定.PNG](https://qiita-image-store.s3.amazonaws.com/0/135302/c217c9f3-4e60-2929-def1-0474dfa9595f.png)

その後に、レベル画像がある領域から、現在登場しているポケモンアイコンの最大サイズ分だけの
領域を探索する。
赤枠で囲ったレベル画像以外の部分が探索する領域であり、全体の数分の１程度の探索で済む。

![LV認識１.PNG](https://qiita-image-store.s3.amazonaws.com/0/135302/63374b9d-6184-4b90-05c8-bf290eb6e34c.png)

これによって背景色が大部分占める領域を調べなくて済む。