とりあえず、OpenCVを使って顔検出したい。
手順
- OpenCVのインストール
- object-markerでアノテーションを作成
- create-samplesでvecファイルを生成
- vecを元にカスケード生成
- カスケードを元に、サンプル作成
※アノテーション=画像に対する特徴箇所(座標, 大きさ)
※カスケード=検出器
OpenCVのインストール
brewでぶっこんだ
brew tap homebrew/science
cd /usr/local/Library/Taps/homebrew-science
brew install OpenCV
# 必要であれば適宜ライブラリ切替
brew switch opencv 2.4.8.2
brew switch libpng 1.5.18
参考: MacにHomebrewをインストールする - Qiita http://qiita.com/is0me/items/475fdbc4d770534f9ef1
アノテーションの作成
object-markerを使ってアノテーションを作成する。以下から、windows用のバイナリをダウンロードする。
物体検出/追跡研究者のための画像アノテーションツール ObjectMarker - >takminの書きっぱなし備忘録 http://d.hatena.ne.jp/takmin/20100930/1285848450
object-markerの簡単な使い方
- 上記サイトでダウンロードし、zip解凍
- rawdataディレクトリに対象の画像を保存(顔画像等)
- 1000枚ぶっこめば使用に耐えうるらしい(ソースは理由があって出せない)
- ObjectMarker.exeを起動
- 「対象にした部位をマウスで囲みEnter」これをたくさんやる
- 成果物がannotation.txtとして出力されるのでこれを利用する(適宜リネーム)
注意点
- 不正な画像ヘッダや、ふつうじゃないファイル名の画像を突っ込むと落ちるようなので注意
##生成ファイル例
フォーマット: ファイル名 部位の数 x1 y1 w1 h1 x2 y2 w2 h2...
rawdata/audrybt1.jpg 1 128 36 49 50
rawdata/albert.jpg 2 63 23 34 33 55 14 47 47
rawdata/albert.jpg 3 63 23 34 33 55 14 47 47 56 16 44 41
正解データのvecファイルを生成
object-markerで生成したアノテーションを利用し、正解データのvecファイルを生成する。out-face.vecとして保存。
なお、vecはvectorの略だと思われる
% OpenCV_createsamples -info annotation.txt -vec vec-files/out-face.vec -num 200 -w 24 -h 24
カスケードを生成する前に
不正解画像を用意
適当に不正解画像(顔写ってない画像)を用意し、rawdata-ngに保存。1000枚ぐらい。
保存したら不正解画像一覧を「nagativelist.txt」として生成。
% ls -1 rawdata-ng/ | sed -e 's/*$//g' -e 's/^/rawdata-ng\//g' > nagativelist.txt
% head nagativelist.txt
rawdata-ng/001.jpg
rawdata-ng/002.jpg
rawdata-ng/003.jpg
...
カスケードを生成
カスケードとは、所謂検出器のこと。
カスケード型分類器 — opencv 2.2 (r4295) documentation http://>opencv.jp/opencv-2.2/py/objdetect_cascade_classification.html
nposは正解画像枚数、nnegは不正解画像を記載。// 1000枚ぐらい画像用意したいなぁ
枚数間違えたら途中で落ちるので注意
また、-bg用に作った「nagativelist.txt」を「data/」に格納して、コマンド実行したらおちたので、そこも注意
テストなので一旦枚数は絞っておく
% mkdir -p data/out-face
% opencv_traincascade -data ./data/out-face -vec ./vec-files/out-face.vec -bg nagativelist.txt \
-numPos 80 -numNeg 100 precalcValBufSize 1024 -precalcIdxBufSize 1024 -baseFormatSave
旧カスケード生成手順(やんなくていい)
はじめ、下記のopencv_haatrainingでトレーニングファイル作ってたけど、非推奨らしい。
やり方調べたので一応書いておく。
% OpenCV_haartraining -data out-face.xml -vec vec-files/out-face.vec -bg nagativelist.txt -npos 1000 -nneg 1000 -w 24 -h 24
# 妥協した枚数
% OpenCV_haartraining -data out-face.xml -vec vec-files/out-face.vec -bg nagativelist.txt -npos 100 -nneg 300 -w 24 -h 24
カスケードの使い方
生成物が『data/out-face/casscade.xml』として、保存されてるので、それを利用する。
gem install ruby-opencv
サンプル実行
rubyでcascade読み込んで、画像渡して検出させるサンプル
ライブラリ依存で、バグるかもしれないがんばれ
#!/usr/bin/env ruby
require 'opencv'
include OpenCV
if ARGV.size != 1
puts 'Usage: ruby #{__FILE__} Image'
img = './img/test.jpg'
else
img = ARGV[0]
end
img = IplImage.load(img)
faces = OpenCV::CvHaarClassifierCascade.load './cascade.xml'
faces.detect_objects(img.to_CvMat) { |rect|
img.rectangle!(rect.top_left, rect.bottom_right, :color => CvColor::Red)
}
window = GUI::Window.new('detect face')
window.show(img)
GUI::wait_key
以下コマンドで実行
ruby ./obj_detect.rb face.jpg
メモ
一つの顔に、四角がいっぱい出てしまう場合、統合するといいかもしれない
ヒント:Nearest Neighbor(最近傍決定則)
参考資料
- アイエスエス株式会社 "Innovative System Solutions" - OpenCVを使った機械学習 http://www.japan-iss.co.jp/?p=1440
- OpenCV 2.4.2で分類器を作る - shkh's blog http://shkh.hatenablog.com/entry/2012/11/03/052251
- OpenCV 備忘録: OpenCVのカスケード分類器の学習の章を訳してみた http://iwaki2009.blogspot.jp/2013/12/opencv_11.html