マーカーの位置を検出させたいと思ってやってみた。
だいたいOpenCVで学ぶ画像認識を参考にすればいいのだけど、自分なりにまとめてみます。こちらの環境はMac(Lion)、OpenCV2.3、Python2.7です。OpenCVとPythonはMacPortsでインストールしています。
1.学習のためのデータ集め
ここから画像データをダウンロードして、解凍しておきます。
カリフォルニア工科大学のオブジェクト画像データ
URL: http://www.vision.caltech.edu/Image_Datasets/Caltech101/Caltech101.html
URL: http://www.vision.caltech.edu/Image_Datasets/Caltech256/
2.非正解画像の一覧ファイル作成
非正解画像の一覧をNG.txtとして保存します。
# find /hoge/fuga/101_ObjectCategories -name "image*.jpg" > NG.txt
# find /hoge/fuga/256_ObjectCategories -name "[0-9]*.jpg" >> NG.txt
みたいな感じでしょうか。中身は下記のようになります。
/hoge/fuga/101_ObjectCategories/BACKGROUND_Google/image_0004.jpg
/hoge/fuga/101_ObjectCategories/BACKGROUND_Google/image_0005.jpg
/hoge/fuga/101_ObjectCategories/BACKGROUND_Google/image_0006.jpg
/hoge/fuga/101_ObjectCategories/BACKGROUND_Google/image_0007.jpg
...
3.マーカー画像作成
今回は以下のような画像を作りました。80x80pixel、左右対称の画像にしておきます。また、背景の色をグレー(128)としておきます。kakukaku2.pngと名づけました。
4.正解画像の生成
OpenCVのコマンドで作成できます。生成する画像の数を7000としておきます。
# opencv_createsamples -img kakukaku2.png -vec kakukaku2.vec -num 7000
-bgcolor 128 -bg NG.txt -w 24 -h 24
wとhは24がいいみたいです。よくわかりませんが。。。-showコマンドで、どのような正解画像が生成されているかがわかります。非正解画像の上にマーカー画像が変形してペーストされているような画像になります。
5.学習
OpenCVのコマンドで作成できます。非正解画像のうち、4000枚を使用しました(nnegで指定)。もちろん、もっと使用しても構いませんが、計算時間が膨大になるでしょう。テストであれば、正解画像7000、非正解画像4000くらいがいいそうです。
# opencv_haartraining -data kakukaku2 -vec kakukaku2.vec -bg NG.txt
-npos 7000 -nneg 4000 -w 24 -h 24 -mode ALL
6.検出させる
Pythonで下記のようなプログラムを組みました。
import sys
import cv
hc = cv.Load("kakukaku2.xml")
img = cv.LoadImage("news.jpg", 0)
faces = cv.HaarDetectObjects(img, hc, cv.CreateMemStorage())
for (x,y,w,h),n in faces:
cv.Rectangle(img, (x,y), (x+w,y+h), 255)
cv.SaveImage("detected.jpg", img)
ソースコード中のnews.jpgは下記のようなものです。2012年4月30日朝日新聞朝刊1面(東京発行)です。実際のサイズは1936x2592pixelですが、著作権の関係上、小さくして掲載します。
上記のコードで検出させたところ、8つのマーク中、4つのマークを検出しました。detect.jpgの青い四角で囲まれたところが検出されたところです。
次に、HarrDetectObjectsのパラメーターを変更して実施。例えば下記のようにです。
cv.HaarDetectObjects(img, hc, cv.CreateMemStorage(),1.1, 2, 0, (60, 60))
2のあたりがしきい値のようなものっぽい。デフォルトは3なので、2に変更。また、(60,60)の部分は、マーカーの最小の大きさ。このサイズ以上でないと検出しません。この結果は、8つのマーク中、8つ全てを検出しましたが、誤検出(マーカー以外の部分をマーカーとして検出)も2ヶ所ありました。画像の前処理や、サンプル数を増やさないとだめでしょうか。