折しも12/6で私も23歳を迎えました.できれば無事健康体で迎えたかったこの日.
この記事はComputer Vision Advent Calendar 2012の12/7担当分として書かれたものです.
主催者でありながら華麗に遅刻をキメました.これはひどい.
高専時代の後輩でもある@blue_jamくん,お疲れ様でした.そして誕生日メッセージありがとうございます.
さて,コンピュータビジョンにおける極めて重要な要素のひとつに画像特徴量があります.
これまでにたくさんの特徴抽出手法が提案されてきているわけですが,この度は最近の国際会議で発表されたばかりの新しい手法の実装が公開されていたので,それを試して見ることにしました.
画像間対応付けと局所特徴量
一般に言う画像間の対応付けとは,異なる画像間で同じものを写している領域を正しく見つけ対応付けることです.
例えば画像で言うと次のような関係が抽出されるわけです.ちなみにこれはSIFTの例です.
画像間で点同士の対応付けを行うだけでも,カメラキャリブレーションやこれに関係する三次元形状復元であったり,簡単な物体検出なども実現できます.
さらに高度な使い道として物体認識や画像分類などにも使われています.
KAZE局所特徴量
コンピュータビジョンに関するトップカンファレンスの一つであるECCV2012において発表された手法です.
- “KAZE Features”
- Pablo F. Alcantarilla, Adrien Bartoli and Andrew J. Davison.
- http://www.robesafe.com/personal/pablo.alcantarilla/kaze.html
開発者はイギリス・フランスの方ですが,KAZEは「風」を意識しておりプロジェクトwebページに行くと風鈴の画像が載っていますw
実装はOpenCVとBoostを使われています.
個人的には非常に使いやすい.というか,だから今回ブログ記事にしたんですし.(←
手法の詳細まではちょっと調べきれませんので,今回は割愛します.気になった方はpaperの方を参照してください.
ちゃんとした実験もあります.
シミュレーション検証
一応原著の方では同じようなシミュレーションをしてはいるんですが,雰囲気がやっぱみたいじゃないですか.
元画像と,それに回転・スケーリング・加法性ホワイトノイズ・ガウシアンブラーをかけた画像との間で対応付けを行い,正解率を求めるシミュレーションプログラムを書いてみました.
ソースコード
ちょっと長くてすみません.汚いです.
このコードを,上述プロジェクトページからダウンロードしたKAZEのソースと同じ所に置けばコンパイルできます.
プログラム書くのにつかれてきたのでそろそろいろいろ投げやりです(こら
解説
- KAZE特徴量の抽出は付属のサンプルを真似ました
- KAZE特徴量のマッチングはブルートフォースの全探索を行なっているサンプルコードから丸コピしました
- また誤対応の除去は行なっていません
- KAZE特徴はキーポイントの型などが独自なので,cv::drawMatchesで描画するために主導で変換してします
実行方法
Linux Mint 3.6 (Ubutnu 12.04相当)で動きます.
OpenCVは2.4.3を想定しています.またBoostが必要です.
パスが通ってない場合は適切にコンパイルオプションに追加してください.特にcv.hへのパスを書く必要があるので注意してください.
2.4系列依然のOpenCVではリンクするライブラリが若干異なります(nonfreeライブラリが不要,など).
% g++ simulation.cpp KAZE.cpp Ipoint.cpp nldiffusion_functions.cpp utils.cpp -lopencv_core -lopencv_highgui -lopencv_imgproc -lboost_system -lboost_thread -lopencv_legacy -lopencv_features2d -lopencv_nonfree -O3
これでコンパイルしたら,
% ./a.out img.jpg
で実行できます.
画像の変換は
- 矢印の上下キーで,画像サイズを拡大縮小
- 矢印の左右キーで,画像を回転
- zキーで画像にホワイトノイズを強め,xキーで弱める
- cキーで画像にガウシアンブラーを強め,vキーで弱める
でできます.
変換パラメータを変更する度に,パラメータと対応付けの精度がこんなかんじで表示されます.
********** scale factor : 1.2 rotation : -55 degree white noise max power : 45 gaussian blur sigma : 1 SIFT:total: 103, correct: 48 (46%), miss: 55 (53%) KAZE:total: 84, correct: 75 (89%), miss: 9 (10%) ********** scale factor : 1.3 rotation : -55 degree white noise max power : 45 gaussian blur sigma : 1 SIFT:total: 103, correct: 50 (48%), miss: 53 (51%) KAZE:total: 79, correct: 71 (89%), miss: 8 (10%)
この結果は上のスクショと同一状態のときのものですが,SIFTが半分前後誤対応しているのに対してKAZEは1割ですんでいますね.
デモンストレーション
カメラで撮影されたある時点の画像を現在の画像と対応付けてみるサンプルです.
こちらのコードは非常に簡単なので解説は不要かと思います.
コード
実行方法
先ほどと同様です.
% g++ demo.cpp KAZE.cpp Ipoint.cpp nldiffusion_functions.cpp utils.cpp -I$HOME/include -I$HOME/include/opencv -L$HOME/lib -lopencv_core -lopencv_highgui -lopencv_nonfree -lopencv_imgproc -lopencv_legacy -lopencv_features2d -lboost_system -lboost_thread -O3 % ./a.out
スペースキーを押すと現在のカメラ画像を入力として固定し,マッチングを行います.
左上の数字はマッチングの数です.ただBruteForceMatcherは強引に対応付けるのでテンプレートのキーポイント数そのままで固定されちゃいます.
スクショは次のようなかんじ.大きいので縮小して載せています.
全体的にみて
シミュレーションでいろんなパターンを試した限りではSIFTと比べて随分いいかんじでした.
実際のマッチングをしても違いますね.
ただ誤対応除去をしてないので,このあたりをやるとまた違った結果になると思います.
特徴点検出がSIFTよりも顕著性の高いところに出る印象があります.
なので,例えばSIFTで検出されたキーポイントでKAZEの記述をしてみたりその逆をしてみたりするとどうなるか興味があります.
この話,さらに突き詰めると例えばdense samplingしたKAZE特徴量を使ってBoFを求めたりするとどうかな?というふうにも繋がりそうで,大変おもしろそう.
ライブラリの使用方法などに十分習熟してないので,速度などについては評価するつもりはなかったのですが,僕が書いたプログラムの上ではSIFTよりだいぶ遅いですね.
まとめ
局所特徴量を用いた画像間対応付けと言えばComputer Visionの最も重要なタスクのうちの一つとも言えるわけですが,そんな手法の一つであるKAZEを試してみました.
ライブラリとしてはわりと使いやすく,私が数日で目的の使い方ができるようになるように整っていますので,画像間対応付けの精度が必要なタスクをされている方は導入を考えてみるとよいかも知れません.
プログラムはド汚いし,検証する上で考慮すべきことを見落としたりしている可能性が非常に大きいです.深夜に書いたし(←
ご指摘などありましたらぜひコメントください.
Computer Vision Advent Calendar次の担当は@dandelion1124さんです.もう記事が上がっています.
分かりやすいレポート、ありがとうございます。
SIFTより遅いっていうのは、最近の特徴量では相当遅いイメージですね。
位置づけとしては、速度よりも精度を上げたい時に選択肢に入るといったところなのでしょうか。
マシンの処理速度は、どんどん上がっていくと思うので、そういう意味で、これから有望な方法なのかもしれないですね。