2009-10-24
3日で作る高速特定物体認識システム (2) SIFT特徴量の抽出
OpenCV | |
![]()
3日で作る高速特定物体認識システム (1) 物体認識とは(2009/10/18)の続きです。
今回は、画像からSIFT (Scale-Invariant Feature Transform) という局所特徴量を抽出するところを作ってみようと思います。
(注)SIFTは特許がとられているので製品には使えません
SIFT特徴量の抽出
まずは、局所特徴量の代表ともいえるSIFTを試してみます。OpenCVにはSIFTを抽出する関数がなかったのでRob Hess氏がC言語で実装したライブラリを試してみます。内部でOpenCVを使っているので事前にOpenCVのインストールが必要です。実装はOpenCV 1.1でされているみたいですが、2.0でもちょっと手直しすると動きました。Rob Hess氏のホームページからSIFT Feature Detectorのzip版を落とします。解凍するといろいろファイルができますが、SIFTを抽出するのに最低限必要なのは、
siftfeat.c - メイン関数 sift.c sift.h - SIFT抽出用関数 imgfeatures.c imgfeatures.h - SIFT特徴量を描画、保存する関数 utils.c utils.h - ユーティリティ関数 beaver.png - テスト画像
です。これらを自分のプロジェクトに追加します。OpenCV2.0でコンパイルするといくつかエラーが出た*1ので直します。imgfeatures.cの373行目を
cvEigenVV( &M, &V, &E, DBL_EPSILON, 0, 0 );
siftfeat.cの28, 29行目を
char* img_file_name = "beaver.png"; char* out_file_name = "beaver.sift";
同じく72行目を
cvSaveImage( out_img_name, img, 0);
に修正します。まだいろいろ警告は出ますがとりあえずコンパイルできます。beaver.pngという画像で実行すると下のような画像が表示されます。
矢印の始点はキーポイントの位置、矢印の長さはスケール、矢印の向きは勾配強度がもっとも強い向きを表しているようです。SIFTの表示方法はキーポイントの点だけ表示、矢印で表示、円で表示などいろいろあるみたいですね。スケールや勾配強度が何を意味しているかはもう少し調査が必要です。当面は、SIFTのキーポイントの位置とそれぞれの点が128次元の特徴ベクトルで表せることだけおさえとけばいいかな?
それぞれのキーポイントの128次元ベクトルは、beaver.siftというファイルに保存されています。矢印1本につき128個の数値(128次元ベクトル)です。下のようなファイルです。
114 128 <--- キーポイントの数と特徴ベクトルの次元数 101.350182 136.130755 40.169879 0.771085 <--- 1つめキーポイントのX座標, Y座標, スケール, 向き 0 0 0 0 3 1 0 0 2 23 46 15 18 3 0 0 6 20 13 1 <--- インデントされている数字が128次元ベクトル(20個で改行が入る) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 88 36 0 0 81 95 57 47 185 114 2 7 185 155 19 6 19 6 1 22 22 0 0 0 0 0 0 1 0 0 0 0 37 8 0 0 91 12 0 1 185 144 11 35 185 50 0 0 23 28 8 95 40 1 0 0 0 0 0 4 0 0 0 0 0 0 0 0 11 5 0 0 4 2 0 0 49 20 0 0 1 0 0 1 0 0 0 0 0 0 0 0 127.871536 71.100579 15.768590 -2.024589 <--- 2つめのキーポイント 1 2 2 72 63 12 1 1 133 93 1 4 2 7 4 44 133 115 0 0 0 0 0 20 9 4 0 0 0 0 0 0 23 0 1 9 107 20 1 8 133 5 0 0 0 1 5 133 132 14 0 0 0 0 8 133 14 1 0 0 0 0 0 8 26 0 0 0 126 37 8 22 133 47 0 0 0 0 3 52 131 41 0 0 0 0 2 36 1 0 0 0 0 0 0 2 2 0 0 0 34 105 80 24 111 15 0 0 0 1 55 66 79 21 0 0 0 0 0 5 0 0 0 0 0 0 0 0
上の画像の場合、128次元ベクトル114本によって表されるってことですね。この128次元ベクトル114本を物体モデルデータベースに登録しておくことになります。けっこう膨大な数値です。このファイルをよく観察するとどうやらキーポイントはスケールの大きな順(矢印が長い順)に並んでいることがわかります。これまたまだよくわかってないのですが、スケールが大きいキーポイントほど重要と解釈してよいのでしょうか?もし詳しい方がいたらアドバイスください。
キーポイントを点で描画
ここでちょっと改造してみます。キーポイントを矢印ではなく点表示にし、SIFTファイルが1行で1個のキーポイント情報を表すようにします。imgfeature.cの595行目あたりを
// cvLine( img, start, end, color, 1, 8, 0 ); // cvLine( img, end, h1, color, 1, 8, 0 ); // cvLine( img, end, h2, color, 1, 8, 0 ); cvCircle(img, cvPoint(start_x, start_y), 2, cvScalar(0,255,255,255), -1, 0, 0);
とし、同じファイルの523行目あたり(数字20個おきに改行を入れる部分)をコメントアウトします。
// if( j % 20 == 0 ) // fprintf( file, "\n" );
こうすると下のようにキーポイントが点になります。beaver.siftも1つのキーポイントの情報が1行にまとまります。スクリプトで処理するときはこっちの方が楽だと思います。
いくつかの画像でSIFTキーポイントを描画してみます。SIFTが画像のどういうところをキーポイントとしてるか大体想像つきますね。陰陽マークみたいにあまり模様がない画像ではキーポイントが少なくなりがちみたいです。
SIFTの詳細
SIFTのキーポイントは、画像の特徴をよく表している場所ってことはわかりました。では、どういう根拠に基づいてその点が選ばれたのか?128次元ベクトルがどういう風に求められたのか?はアルゴリズムの詳細を詳しく調べる必要があります。SIFTは結構複雑なことをやっていて、ガウシアン平滑化フィルタ、Difference of Gaussian (DoG)、局値検出、画像の微分、強度勾配など画像処理の理論がわかっていないと理解が難しい・・・私もまだおぼろげに理屈がわかってきた程度です。1つ思い違いをしてたのは、SIFTは色情報を使ってないってことかな。実際、グレースケール画像から抽出してます。いくつか参考にした文献を挙げておきます。これらを参考にそのうちC++版のSIFTを作ってみようと思います。
3日で作る高速特定物体認識システム (3) SURFの抽出(2009/10/30)へつづきます。
- SIFTチュートリアル - 藤吉先生によるSIFTの解説資料、図が豊富でわかりやすい。
- SIFTを1から組むブログ - 手順を追って少しずつ実装しているのでわかりやすい。途中でららら♪ってごまかしてるけど(笑)
- Rob Hess氏のSIFT特徴量抽出モジュールつかってみる - Rob Hess氏のプログラムの実行方法です。
- SIFT++ - 別の実装。こっちも試してみたい。
- SIFT for Matlab - Matlabによる実装。
- Scale-invariant feature transform - Wikipediaの記事。
- Keypoint detector - SIFTの提案者Lowe氏のデモ。
- Lowe, D. G.: Object recognition from local scale-invariant features (PDF), Proc. of IEEE Intl. Conf. on Computer Vision (ICCV), pp.1150-1157 (1999) - SIFTの原論文
- Lowe, D: Distinctive imagefeatures from scale-invariant keypoints (PDF), Proc. of Intl. Journal of Computer Vision (IJCV), 60(2), pp.91-110 (2004) - SIFTの原論文
このシリーズの記事一覧
- 3日で作る高速特定物体認識システム (1) 物体認識とは(2009/10/18)
- 3日で作る高速特定物体認識システム (2) SIFT特徴量の抽出(2009/10/24)
- 3日で作る高速特定物体認識システム (3) SURFの抽出(2009/10/30)
- 3日で作る高速特定物体認識システム (4) 特徴点のマッチング(2009/11/2)
- 3日で作る高速特定物体認識システム (5) 物体モデルデータベースの作成(2009/11/14)
- 3日で作る高速特定物体認識システム (6) 線形探索を用いた特定物体認識(2009/11/22)
- 3日で作る高速特定物体認識システム (7) 最近傍探索の高速化(2009/12/12)
- 293 http://www.google.co.jp/url?sa=t&rct=j&q=sift&source=web&cd=2&ved=0CDcQFjAB&url=http://d.hatena.ne.jp/aidiary/20091024/1256384360&ei=cjuETsTcEIKNmQW0p6kE&usg=AFQjCNEwT36O_5CVkYIKQC9loek84wXgmw
- 251 http://d.hatena.ne.jp/mjmania/20100123/1264221761
- 232 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4ADBF_jaJP297JP297&q=open+cv+物体認識
- 230 http://www29.atwiki.jp/suffix/pages/554.html
- 227 http://www.google.co.jp/url?sa=t&rct=j&q=sift特徴量 記述 opencv&source=web&cd=4&ved=0CDkQFjAD&url=http://d.hatena.ne.jp/aidiary/20091024/1256384360&ei=jpqFTqeeN4bemAWHhoEK&usg=AFQjCNEwT36O_5CV
- 215 http://www.google.co.jp/search?q=SIFT&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja-JP:unofficial&client=firefox-a
- 178 http://www.google.co.jp/search?q=SIFT特徴量 SURF特徴量&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:ja:unofficial&client=firefox-a
- 167 http://www.google.co.jp/search?hl=ja&q=sift特徴量+つくる&sourceid=navclient-ff&rlz=1B3GGGL_jaJP289JP290&ie=UTF-8
- 154 http://pipes.yahoo.com/pipes/pipe.info?_id=33330c385f80af52ec4bc6b27e219e4e
- 138 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=rbL&q=sift+opencv&btnG=検索&lr=lang_ja&aq=f&oq=








