こんにちは。河本です。
僕はサイゼリヤに行くとまずキッズメニューの間違い探しを解くんですが、
今回は難しすぎたので、大人の力(=画像処理)で解決することにしました。
2014年9月版。みんなもやってみよう! |
やり方
いろいろ書いてますが、左面と右面の違う部分を色の差分から見つけてるだけです。
紙の歪みを吸収するために、少しややこしいことをしてます。
↑の写真です。普通にiPhoneで撮りました。
(2) ページ領域を抽出する
画像からページの部分を見つける必要があります。
今回は面倒なので、左側は手作業で指定しました。
角を手作業でタグ付けして・・・
こっちは手作業。 |
台形補正しても、紙が曲がってたので少し歪んでる。 |
右面は自動で見つける |
両方歪んでますが、そもそも紙が曲がってるので射影変換ではこれが限界です。
左面と右面
ざっくり両面の画像が取れましたが、歪みのため単純比較はできません。
例えば、左と右のピクセルの色距離を単純に比較(AbsDiff)するだけでは、こんなことになってしまいます:
左面と右面の同じ位置のピクセルの色の距離。これでは間違い部分は見つけられない。 |
左面の小さい領域を取り出し、
100x100の小さい領域。 |
見つけた領域の左面と右面を比較、差分抽出(absDiff→threshold→erode→dilate)します。
文字の輪郭はどうしても差分ノイズが乗りますが、erodeで大体消えます。
(左)差分画像 (右)元のページ
ちゃんと答えのところに大きい差分が出てる。
最後に差分画像から輪郭抽出(findContours)して、「間違い」を探します。
見つけた領域を元の画像に描画したのが以下です:
誤認識は3つあります。
また、一個だけ見つけられていないのがありますね。(どこでしょう?)
実際には二値化のステップの閾値を下げれば見つけられますが、そのぶん誤認識も増えます。
今回の問題では、精度を下げてでも再現率を上げた方がいいですね。
というわけで、一番最初にページ領域を手作業でタグ付けする部分以外は、全自動で間違い探しを解くことができました。
さいごに
・最初にテンプレを手作業で作らないといけないのは、いろいろ自動化する方法があります。例えば「同じような画像が2つ並んでる一番大きい領域を探す」みたいなことをしたり、机を見つけて除外するとかすればいいんですが、ちょっと汎用性が落ちそうなので今回は止めました。
・サイゼリヤのサイトに過去の間違い探しの画像データが上がってます。元画像なので、精度よく間違い認識できます。答えも載ってるけどな!
歪みが無いので簡単に間違いを認識できる。 |
・iPhoneアプリにしたり、メニューに直接答えを投影したりとか色々見せ方が考えられますね。暇な時作ります。
・OpenCVが使えれば世の中の大抵の問題は解決できる。