1Click飲みRomoCartTempescope色色[:iroiro]Other Projects

2014年11月16日日曜日

サイゼリヤの間違い探しが難しすぎたので大人の力で解決した

こんにちは。河本です。
僕はサイゼリヤに行くとまずキッズメニューの間違い探しを解くんですが、
今回は難しすぎたので、大人の力(=画像処理)で解決することにしました。
2014年9月版。みんなもやってみよう!
(以下、間違い探しの答えが出てきます。見たくない人は↑の画像で頑張ってから読もう。)


やり方

いろいろ書いてますが、左面と右面の違う部分を色の差分から見つけてるだけです。
紙の歪みを吸収するために、少しややこしいことをしてます。

(1) 間違い探しページの写真を撮る
↑の写真です。普通にiPhoneで撮りました。

(2) ページ領域を抽出する
画像からページの部分を見つける必要があります。

今回は面倒なので、左側は手作業で指定しました。
角を手作業でタグ付けして・・・
こっちは手作業。
射影変換で台形補正します。OpenCVならWarpPerspectiveです。
台形補正しても、紙が曲がってたので少し歪んでる。
次に、左側の画像をテンプレとして使って、右側の画像から紙部分をSURF+マッチングでオブジェクト認識して見つけます。(参考:whoopsidaisies's diary: OpenCVで画像の特徴抽出・マッチングを行う
右面は自動で見つける
そんなわけで、両面の画像ができました。
両方歪んでますが、そもそも紙が曲がってるので射影変換ではこれが限界です。
左面と右面


(3) 局所差分を算出
ざっくり両面の画像が取れましたが、歪みのため単純比較はできません。
例えば、左と右のピクセルの色距離を単純に比較(AbsDiff)するだけでは、こんなことになってしまいます:
左面と右面の同じ位置のピクセルの色の距離。これでは間違い部分は見つけられない。
そこでどうするかというと、
左面の小さい領域を取り出し、
100x100の小さい領域。
再度オブジェクト認識で右面から同じ領域を見つけ、


見つけた領域の左面と右面を比較、差分抽出(absDiff→threshold→erode→dilate)します。
文字の輪郭はどうしても差分ノイズが乗りますが、erodeで大体消えます。

この局所領域を少しずつずらして、ページ全体の差分画像を作り上げます:
(左)差分画像 (右)元のページ
ちゃんと答えのところに大きい差分が出てる。

(4) 間違い部分の抽出
最後に差分画像から輪郭抽出(findContours)して、「間違い」を探します。
見つけた領域を元の画像に描画したのが以下です:

誤認識は3つあります。
また、一個だけ見つけられていないのがありますね。(どこでしょう?)
実際には二値化のステップの閾値を下げれば見つけられますが、そのぶん誤認識も増えます。
今回の問題では、精度を下げてでも再現率を上げた方がいいですね。

というわけで、一番最初にページ領域を手作業でタグ付けする部分以外は、全自動で間違い探しを解くことができました。


さいごに

・最初にテンプレを手作業で作らないといけないのは、いろいろ自動化する方法があります。例えば「同じような画像が2つ並んでる一番大きい領域を探す」みたいなことをしたり、机を見つけて除外するとかすればいいんですが、ちょっと汎用性が落ちそうなので今回は止めました。

サイゼリヤのサイトに過去の間違い探しの画像データが上がってます。元画像なので、精度よく間違い認識できます。答えも載ってるけどな!
歪みが無いので簡単に間違いを認識できる。
・iPhoneアプリにしたり、メニューに直接答えを投影したりとか色々見せ方が考えられますね。暇な時作ります。

・OpenCVが使えれば世の中の大抵の問題は解決できる。

2 件のコメント:

  1. 恒星間戦争で敵布陣を局所点カメラアイを使って平面なり3次元空間地図に補正します。複数光子発生地点から情報摂取局所点までの距離がバラバラ。これを補正すると従来気付かなかった極小区間の素粒子干渉が解ける。電磁現象地図の補正に興味あればよろしく。

    返信削除
  2. 参考にしました。作ってみました。1箇所見つけられなかった箇所は、2値化の際、網の濃淡部が同じになってしまったということなんですね。

    返信削除