2011/11/19

OpenCVを使った簡単で楽しい画像処理

OpenCVというライブラリを使うと複雑な画像処理プログラムをかなり簡単に書くことができる。というか実際にほとんど一日勉強しただけのようなレベルのぼくでも、結構難しそうな問題を解けるプログラムを書けたので、ちょっとここで紹介してみたい。


やりたかったことは、上のようなイメージからホールを検出すること。紙に穴が空いているのだが、これが何個どの位置にあるのかを検出したい。穴の輪郭は若干ギザギザしているし、互いに重なっていることもあるので、素直な円検出アルゴリズムはうまく動かない。自動でやるにはちょっと難しそうな問題でしょう? これがOpenCVを使うと数十行のプログラムで解くことができる。

解き方としては、穴が検出しやすくなるように画像をステップバイステップで単純化しながら、パターンマッチで穴を検出すればいいようだ。そういうやりかただと次のような流れになる。

まずは画像をガウシアンフィルタに通して平滑化してから、モノクロに変換する。


次に適当な明るさをしきい値として2値画像に変換する。特別に明るい1ピクセルなどが元画像にあったとしても、平滑化でならされているので、このステップで消えてなくなる。


標準的な穴と同じ大きさで同じ形の画像をテンプレートとしてマッチングを行うと、穴の中心と思われる部分が色の濃くなった画像が得られる。この濃さが「テンプレートと画像のその位置とがマッチしている度合い」を表している。


穴の中心だけを残すために2値化フィルタを再度かける。


この点の輪郭を抽出して、その輪郭の重心を求めると、それがそれぞれの穴の中心の座標ということになる。


検出した座標を中心として円を描画してみるとこうなる。


同じ円を元の画像に重ねてプロットすると次のようになる。重なった穴も含めてすべての穴が見事に検出されているのがわかると思う。画像処理の経験は特になくてもすぐにここまでできるようになるのだからOpenCVは素晴らしい。