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

OpenCVで大抵の問題は解決する

自動で間違い見つけるプログラム作った。意外とちゃんと作るの難しかった。(一個見逃してるし。)明日まとめる。

サイゼリヤのキッズメニューに載っている間違い探しは、大人が本気を出しても苦戦する難易度で知られています。そこで、画像処理ライブラリOpenCVを用いて紙面の写真から間違い箇所を自動検出するパイプラインを構築しました。

仕組み

紙のたわみや歪みがあるため、単純な画像全体のピクセル差分比較では位置ズレによるノイズしか残りません。紙面の歪みを局所的に吸収しながら比較するアプローチをとっています。

  1. 射影変換: 撮影画像から四隅を指定し、透視変換(WarpPerspective)で正面からの平面画像に台形補正。

  1. 局所領域のマッチング: 左側の画像を100×100ピクセルの小さな領域に分割し、SURF特徴量を用いて右側の対応する位置を探索。

  1. 局所差分の算出とノイズ除去: 小領域ごとに差分(AbsDiff)を取り、二値化とモルフォロジー演算(Erode / Dilate)で文字輪郭の微小なズレを平滑化。

小領域を少しずつずらしながらページ全体の差分画像を再構築し、最終的に輪郭抽出(findContours)にかけることで、紙の曲がりを吸収しながら高精度に間違い箇所を炙り出すことができます。

Updates

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

こんにちは。河本です。

僕はサイゼリヤに行くとまずキッズメニューの間違い探しを解くんですが、

今回は難しすぎたので、大人の力(=画像処理)で解決することにしました。

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が使えれば世の中の大抵の問題は解決できる。


他の分析エントリ

- 山手線リアルタイム混雑情報で遊んでみよう
- 140文字の「重み」を言語毎に比較してみた
- 世界で一番住みやすい場所を計算してみた
- 建物のWifiをホッピングして東京から大阪まで通信できるか
- Topcoderに一番有利な時間帯を調べてみた
- Wikipediaのデータで人生解析をしてみよう
- 明日の天気を過去の似た日から合成して可視化してみよう
- 「頭痛」を含むツイートと気圧の関係を調べてみた