2014年4月26日土曜日

OpenCVを使って一般物体認識エンジンを作成する

画像中の物体のクラスを認識する処理を、一般物体認識という。

一方、同インスタンスを認識する処理を特定物体認識という。

画像の feature や 機械学習手法をある程度勉強すれば、OpenCVを用いてどちらの識別器をつくることも可能だ。

今回は、一般物体認識の識別器をつくる方法をまとめる。

以下の準備が必要だ。

1.画像の収集
2.環境の準備
3.訓練
4.検証

順に、はまった点なども含めて記載していこうと思う。

1.画像の収集

認識したいクラスの画像(正事例)を少なくとも 3000 枚程度集める。
(例えば車を横からとらえた画像であれば、様々な種類の車、撮影角度、明るい、暗い、などの条件で収集する。)

これは Microsoft のBING APIを使うと、無料で5000回のリクエストを投げることが出来るので、便利だ。

画像を集めたら、画像中からクラスを表す部分を出来るだけ正確に抜き出す。
出来るだけ認識したい部分だけを、欠けること無く切りだすと良い。

また、認識したクラス以外の画像(負事例)もたくさんあつめる。少なくとも正事例画像の半分は集めること。
また、正事例として切り出した画像の倍程度の解像度で使用することを前提に切り出すと良い。


画像を切り出したら、学習に必要なファイルを作成する。
正事例と負事例では、異なるフォーマットのファイルが必要だ。

正事例

以下のフォーマットでsamplesファイルを作成しておく。

[画像ファイルへのパス] [N(画像中の物体の個数)] [クラスを囲む矩形の左上座標x] [クラスを囲む矩形の左上座標y] [width] [height] …N回繰り返し

(画像枚数分の行)

ex)
./positive/img.jpg 2 110 150 45 45  40 30 20 20

これは画像が切り出せていれば簡単なプログラムで出力すれば良いだろう。

負事例

正事例と違い、クラスを囲む矩形の矩形の情報はいらない。以下のフォーマットとなる。

[画像ファイルへのパス]
ex)
./negative/img.jpg

以上で、訓練画像の実体とそれらを示す samples ファイルが出来た。



2.環境の準備


OpenCV環境を使用する。

Androidで動作させたい場合は、OpenCV 2.4.1 までを使用すれば、OpenCV Manager をインストールする必要はない。(その変わりアプリサイズは大きくなる)
用途に合わせてバージョンを選択すれば良いだろう。

今回は、OpenCV Managerを使わずに、iPhone、Android端末上で動作させたかったので、
OpenCV 2.4.1 を使用した。

Windows環境を前提とする。

OpenCVの公式サイトからダウンロードする。

訓練環境はWindowsで作成する。
・Windows
以下から、2.4.1を選ぼう。

http://opencv.org/downloads.html


Androidに搭載したいので、以下をダウンロードしておく。
(Android開発環境ADTは構築済みとする)
・Android
http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.1/


OpenCVをビルドする

まずは、OpenCVをビルドする。RAMを贅沢に使える環境が増えているので、32bit版を使用していても 1 GB制限を外したいことが主な理由だが、ソースコードを書き換えて使う場合、ビルドは必須だ。

CMakeのダウンロードと使い方。

CMakeをダウンロードする。
http://www.cmake.org/

CMakeを使って、OpenCVのコードをvisualstudioのプロジェクトファイルを作成する。

以下が詳しくてありがたい。(3つ)
  • http://cvwww.ee.ous.ac.jp/oc20inst.html
  • http://ameblo.jp/banquet-of-merry-widow/entry-11105368931.html
  • http://blogs.yahoo.co.jp/nobuyuki_tsukasa/2803954.html
visualstudioのプロジェクトファイルが出来たら、開けばソースからビルド出来る。
(割りと時間がかかる。)

x32のOpenCVを使った方がはまりづらいが、RAM使用量の制限がうざい。
解除するには以下のサイトが参考になる。
http://d.hatena.ne.jp/manji602/20111214/1323834770


次に、学習用のプロジェクトをビルド使用。moduleに含まれている。

visualstudioを使ったが、インクルードするディレクトリなどは、mkファイルを参照しながら
追加した。
※以下は、opencv241_winにOpenCV2.4.1のソースを展開した前提。

○haartraining opencv visual studio(VC++)
○createsamples opencv visual studio(VC++)

・インクルードディレクトリ
C:\opencv241_win\build\include;C:\opencv241_win\build\include\opencv;C:\opencv241_win\build\include\opencv2;

・ライブラリディレクトリ
C:\opencv241_win\build\x86\vc10\lib;C:\opencv241_win\build\common\tbb\intel64\vc10;

opencv_imgproc241.lib;opencv_highgui241.lib;opencv_features2d241.lib;opencv_objdetect241.lib;opencv_calib3d241.lib;opencv_core241.lib;


○traincascade opencv visual studio(VC++)
・インクルードディレクトリ
C:\opencv241_win\build\include;C:\opencv241_win\build\include\opencv;C:\opencv241_win\build\include\opencv2;

・ライブラリディレクトリ
C:\opencv241_win\build\common\tbb\ia32\vc10;C:\opencv241_win\build\x86\vc10\lib;

opencv_core opencv_ml opencv_imgproc opencv_objdetect opencv_highgui opencv_calib3d opencv_video opencv_features2d opencv_flann opencv_legacy

・ライブラリ
opencv_imgproc241.lib;opencv_highgui241.lib;opencv_features2d241.lib;opencv_objdetect241.lib;opencv_calib3d241.lib;opencv_core241.lib;opencv_flann241.lib;opencv_contrib241.lib;opencv_ml241.lib;opencv_video241.lib;opencv_legacy241.lib


VC++のうざい警告が出るので、以下でやめさせる。

指定した警告を無視するで以下を指定。
4290;4996

また、デバッグビルドだとうまく動作せず、以下のエラーが出た。
http://grayhole.blogspot.jp/2012/04/isctypec-expression-unsignedc-1-256.html

リリースビルドだと動作したのでとりあえず放置。


学習用正事例サンプルの作成


正事例データを作成するために、createsampleプロジェクトを使用する。

createsamplesの使い方


> createsamples.exe -info samples.txt -vec ./positives/vec/positive_samples.vec -num 2 -h 10 -w 10

samples.txtは1の②で作成したファイルを使用する。


・h, wは 10~50 が良いらしい


作成されたsamplesの確認方法


> createsamples.exe -vec ./positives/vec/positive_samples.vec -w 10 -h 10

・h, wは 作成時の値を指定する


学習

createsamplesの出力したvecファイルを正事例用に使用する。

①haartrainingを使用する。
1世代前の学習。Haar-like特徴のみ使用できる。
②traincascadeを使用する。
最新の学習プログラム。以下のアルゴリズムを指定できる。
Haar-like
HOG
LBP

②のほうが新しく書き直されたもので、①も含むので基本②を使えば良い。
というか、②しか使ったことが無い。

traincascade

重要なパラメータは以下。


  • data:出力先ディレクトリ(つくってくれないので、事前につくっておくこと)
  • vec:positiveサンプルのvecファイル
  • bg:negativeサンプルのリストファイル
  • numPos:採用するポジティブサンプルの数
  • numNeg:採用するネガティブサンプルの数
  • numStages:AdaBoostステージ数
  • w:横(positive vecに合わせる)
  • h:縦(positive vecに合わせる)
  • min_hit_rate:各ステージの最少ヒット率
  • maxFalseAlarmRate:半分を超えない識別機は意味がないので排除する
  • bgcolor:認識したい物体の背景に多い輝度を指定(または認識したい物体と遠い輝度)



訓練が成功すると学習結果が出来上がる。
辞書がうまく成長しない場合、以下をチェックする。


  • 正事例数
  • 負事例数
  • 正事例と負事例の解像度比
  • 特徴量
  • ステージ数


AndroidでOpenCVを使う

CDTは入れておこう!
EclipseのNew Software Instoreから入れる。
nativeのソースをコンパイルしたいので、windows用OpenCVのlibsにあるlibとdllを指定する。
デフォルトだと以下、OpenCVをローカルでビルドした場合、build先のディレクトリにする。
各種lib → [OpenCV展開ディレクトリ]\build\x86\vc10\lib
各種dll → [OpenCV展開ディレクトリ]\build\x86\vc10\bin


NDKもダウンロードしておこう!
ダウンロードして、好きな場所に展開したら、
NDKの場所をEclipseに設定出来るので、ディレクトリを設定する。
さらに、ndkのビルドをwindows用のコマンドに変更する。

SurfaceViewは理解しておこう!
http://qiita.com/croquette0212/items/24dc2b6de3730e831aab


CDTでインクルードに成功し、追加ライブライを追加できたら、Android.mkファイルを手直しする必要があるかもしれない。
必要であれば、mkファイルでインクルードするOpenCVのライブラリの場所を、ローカルのOpenCVのパスに変更する。

0 件のコメント:

コメントを投稿