はじめに
シーン認識エンジンを実装してみる。
作成手順に付いては、このサイトが詳しい。具体的な処理を書き下ろすと以下のようになる。
- 局所特徴量の抽出
- Visual Wordの作成
- ヒストグラムの作成
- SVMの作成
- 予測器の作成
局所特徴量の抽出
opencv2にはDescriptorExtractorなるクラスが用意されている。このクラスは静的メソッドcreateを持ち、その引数に局所特徴量の種類を文字列として渡すだけで、以下の抽出器を作成することができる。
- SIFT
- SURF
- ORB
- BRIEF
src
は入力画像、keypoints
は格子点座標などの情報、descriptors_
は出力値(特徴ベクトル)である。出力値の型はcv::Mat
である。Visual Wordの作成
先に計算した特徴ベクトルの集合から、いくつか適当に取り出し、これらをクラスタリングする。opencv2にはこれを実行するクラスBOWKMeansTrainerが用意されている。このクラスはメソッド
add
とcluster
を提供する。
add
で特徴ベクトルの集合を渡し、
cluster
でクラスタリングを実行する。
ここで、trainer_
はBOWKMeansTrainerのオブジェクト、descriptors
は特徴ベクトルの集合、vocabulary
は出力値(各クラスタの重心座標)である。ヒストグラムの作成
ここでもopencv2を使用する。クラスBOWImgDescriptorExtractorを利用すれば良い。 先に計算したvocabulary(重心座標の集合)を渡し、 ヒストグラムを計算する。 ここで、
bow_extractor_
はBOWImgDescriptorExtractorのオブジェクト、src
は入力画像、keypoints
は特徴量の抽出時に使用した格子点座標、histogram
は出力値(ヒストグラム)である。1枚の画像から1つのヒストグラムが作成される。ヒストグラムの頻度の総和は1に規格化される。SVMの作成
シーン認識に有効とされるカーネルは以下の2つである。
- χ2カーネル
- ヒストグラムインターセクションカーネル
execute
の引数positive
とnegative
はそれぞれ室内画像、室外画像から作られたヒストグラムの集合である。4行目でこれを1つに統合する。9,10行目で、室内か室外かを区別するラベルを作成する。12,13行目でカーネルを作成する。そして、16,17行目で学習を行っている。ソースから分る通り、実際に計算を行っているのはlibsvmである。
学習のあと、svmのオブジェクトを保存する。
shogunはオブジェクトをシリアライズするメソッドsave_serializable
を提供する。これを利用した。ここまでで、識別器が完成した。予測器の作成
save_serializable
の逆を行うメソッドload_serializable
を使う。
9行目でsvmオブジェクトを再現し、21行目で予測する。結果はshogun::CLabels
型で返される。23行目でこれを保存している。各種パラメータの設定
特徴量抽出
記述子はSIFTを採用した。次元数は128である。格子間隔は5ピクセルである。クラスcv::KeyPoint
のメンバ変数size
の値は(16,24,32)の3つ、同じくメンバ変数angle
の値は(0度,120度,240度)とした。Visual Wordの作成
作成するクラスタの数を1万とした。入力値とした記述子の数は648659個である。これは全画像のおよそ1/60の枚数から算出した記述子の数である。ヒストグラムの作成
近傍探索のアルゴリズムとしてBruteForceを選択した。その他
最初に述べたように、15カテゴリを室内と室外の2カテゴリに分けた。室内の画像数は室外の画像数のおよそ半分となった。室内画像に、左右反転画像を追加し2カテゴリの画像数を同程度とした。結果
K-分割交差検定を行った。K=3である。全画像を3分割し、そのうち1つをテスト群、残りを訓練群とした。3回繰り返し認識率の平均値を計算した。
χ2カーネル
width=0.5, c=10indoor | outdoor | |
---|---|---|
認識率 | 0.820 | 0.819 |
ヒストグラムインターセクションカーネル
β=1,c=10indoor | outdoor | |
---|---|---|
認識率 | 0.781 | 0.827 |
ガウスカーネル
width=0.5,c=100indoor | outdoor | |
---|---|---|
認識率 | 0.813 | 0.805 |
今後の予定
- ソースコードを公開する。
- 今回の実装は、シーン認識の骨組みを作ることが目的であった。使用したアルゴリズムはどれも標準的なものばかりである。今回採用したヒストグラム(Bag Of Visual Words)を連続分布で置き換える手法(Gaussian Mixture Model)や、Fisher's Vectorと呼ばれる記述子についても考察する。
- 今回は2カテゴリを識別する判別器を作成した。これを15カテゴリに拡張する。
- 今回の実装では計算時間を度外視した。高速化も考慮に入れる。hadoopを使った並列化も考察する。
- Webブラウザを通して画像を受け付け、判別結果を返す仕組みをdjangoを使って実装する。
参考サイト
- n_hidekeyの日記:画像認識について大変分りやすくまとめられている。
- LSP15:画像セット
- shogun:SVMライブラリ
- More Than Technical:opencvを用いた画像認識の実装例
- 「大規模データを用いた一般物体認識・シーン認識の潮流と理論」:原田達也氏のまとめ。先日のSSII2012でも講演されていた。
追記
ソースを公開すると言いつつしてないですね。ごめんなさい。 以下3つを公開します。
CommonはSvmPredictor/SvmTrainerで共有しているファイルです。
こんにちは突然失礼いたします。
返信削除私も今shogunを利用したプログラムを作成しているのですが、日本語での資料がなかなか見つからず困っております。
もしよろしければSVM(shogun)部分だけでもソースコードを公開していただけませんでしょうか?
了解しました。
返信削除