2012年6月18日月曜日

シーン認識の実装

はじめに 

 

シーン認識エンジンを実装してみる。
作成手順に付いては、このサイトが詳しい。具体的な処理を書き下ろすと以下のようになる。
  1. 局所特徴量の抽出
  2. Visual Wordの作成
  3. ヒストグラムの作成
  4. SVMの作成  
  5. 予測器の作成
 学習型アルゴリズムであるので、大量の画像を用意しておく必要がある。今回使用した画像セットはLSP15である。15個のカテゴリに分類された室内・室外画像である。各カテゴリには、縦横200から300ピクセル程度の画像が200から300枚ほど含まれている。今回は、15個のカテゴリを室内と室外の2カテゴリに分類し直し、室内・室外を判定する認識エンジンを考察した。実装に当たっては、opencv2など既存のライブラリを最大限利用することとした。

 局所特徴量の抽出

 

 opencv2にはDescriptorExtractorなるクラスが用意されている。このクラスは静的メソッドcreateを持ち、その引数に局所特徴量の種類を文字列として渡すだけで、以下の抽出器を作成することができる。
  1. SIFT
  2. SURF
  3. ORB
  4. BRIEF
さらに、局所特徴量を密に取り出すため一定間隔で画像上の画素を拾い、その点での特徴量を計算した。 ここでsrcは入力画像、keypointsは格子点座標などの情報、descriptors_は出力値(特徴ベクトル)である。出力値の型はcv::Matである。

Visual Wordの作成 

 

先に計算した特徴ベクトルの集合から、いくつか適当に取り出し、これらをクラスタリングする。opencv2にはこれを実行するクラスBOWKMeansTrainerが用意されている。このクラスはメソッドaddclusterを提供する。 addで特徴ベクトルの集合を渡し、 clusterでクラスタリングを実行する。 ここで、trainer_はBOWKMeansTrainerのオブジェクト、descriptorsは特徴ベクトルの集合、vocabularyは出力値(各クラスタの重心座標)である。

ヒストグラムの作成 

 

ここでもopencv2を使用する。クラスBOWImgDescriptorExtractorを利用すれば良い。 先に計算したvocabulary(重心座標の集合)を渡し、 ヒストグラムを計算する。 ここで、bow_extractor_はBOWImgDescriptorExtractorのオブジェクト、srcは入力画像、keypointsは特徴量の抽出時に使用した格子点座標、histogramは出力値(ヒストグラム)である。1枚の画像から1つのヒストグラムが作成される。ヒストグラムの頻度の総和は1に規格化される。

SVMの作成 

 

シーン認識に有効とされるカーネルは以下の2つである。
  1. χ2カーネル
  2. ヒストグラムインターセクションカーネル
今回の考察では、これらをサポートしているSVMライブラリshogunを利用した。このライブラリは複数の既存ライブラリを共通のインターフェースから使えるようにしたラッパーである。計算の手順は以下の通りである。 メソッドexecuteの引数positivenegativeはそれぞれ室内画像、室外画像から作られたヒストグラムの集合である。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=10


indoor outdoor
認識率 0.820 0.819

ヒストグラムインターセクションカーネル

β=1,c=10


indoor outdoor
認識率 0.781 0.827

ガウスカーネル

width=0.5,c=100


indoor outdoor
認識率 0.813 0.805

 

今後の予定


  1. ソースコードを公開する。
  2. 今回の実装は、シーン認識の骨組みを作ることが目的であった。使用したアルゴリズムはどれも標準的なものばかりである。今回採用したヒストグラム(Bag Of Visual Words)を連続分布で置き換える手法(Gaussian Mixture Model)や、Fisher's Vectorと呼ばれる記述子についても考察する。
  3. 今回は2カテゴリを識別する判別器を作成した。これを15カテゴリに拡張する。
  4. 今回の実装では計算時間を度外視した。高速化も考慮に入れる。hadoopを使った並列化も考察する。
  5. Webブラウザを通して画像を受け付け、判別結果を返す仕組みをdjangoを使って実装する。

参考サイト

 

  1. n_hidekeyの日記:画像認識について大変分りやすくまとめられている。
  2. LSP15:画像セット
  3. shogun:SVMライブラリ
  4. More Than Technical:opencvを用いた画像認識の実装例
  5. 「大規模データを用いた一般物体認識・シーン認識の潮流と理論」:原田達也氏のまとめ。先日のSSII2012でも講演されていた。

追記


ソースを公開すると言いつつしてないですね。ごめんなさい。 以下3つを公開します。
  1. SvmPredictor
  2. SvmTrainer
  3. Common
CommonはSvmPredictor/SvmTrainerで共有しているファイルです。

2 件のコメント:

  1. こんにちは突然失礼いたします。
    私も今shogunを利用したプログラムを作成しているのですが、日本語での資料がなかなか見つからず困っております。
    もしよろしければSVM(shogun)部分だけでもソースコードを公開していただけませんでしょうか?

    返信削除