OpenCV + haardetectobjects(物体検出)その2

正解を20000、非正解を10000にしたら、今度はマーカーをほとんど検出しなくなりました。こういうもんのなんだろうか。。。わからなくなってきたぞhaardetectobjects。

http://lab.cntl.kyutech.ac.jp/~kobalab/nishida/opencv/haartraining_jp.htm

を参考に、パラメーターを調整中。。。

OpenCV + haardetectobjects(物体検出)

マーカーの位置を検出させたいと思ってやってみた。

だいたい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と名づけました。

NewImage

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ですが、著作権の関係上、小さくして掲載します。

NewImage

上記のコードで検出させたところ、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ヶ所ありました。画像の前処理や、サンプル数を増やさないとだめでしょうか。