Coding Memorandum

プログラミングに関する備忘録

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

OpenCVのSURF実装

画像認識などで使われる局所特徴量SURFの特徴量記述は次の式で定義される。(ここではdx, dyの詳細は説明しない)

これを4x4領域のピクセル毎に求めて結合した64次元のベクトルがSURFとなる。

OpenCV(2.0以降)の該当コードは次のようになっている。

/* Construct the descriptor */
vec = (float*)cvGetSeqElem( descriptors, k );
for( kk = 0; kk < (int)(descriptors->elem_size/sizeof(vec[0])); kk++ )
    vec[kk] = 0;
double square_mag = 0;

/* 64-bin descriptor */
for( i = 0; i < 4; i++ )
    for( j = 0; j < 4; j++ )
    {
        for( y = i*5; y < i*5+5; y++ )
        {
            for( x = j*5; x < j*5+5; x++ )
            {
                float tx = DX[y][x], ty = DY[y][x];
                vec[0] += tx; vec[1] += ty;
                vec[2] += (float)fabs(tx); vec[3] += (float)fabs(ty);
            }
        }
        for( kk = 0; kk < 4; kk++ )
            square_mag += vec[kk]*vec[kk];
        vec+=4;
    }
}

/* unit vector is essential for contrast invariance */
vec = (float*)cvGetSeqElem( descriptors, k );
double scale = 1./(sqrt(square_mag) + DBL_EPSILON);
for( kk = 0; kk < descriptor_size; kk++ )
    vec[kk] = (float)(vec[kk]*scale);

求めた特徴量を正規化する処理が入っている(28-30行)。SURFの元論文には正規化に関する記述は見受けられなかったので、OpenCV特有の処理であるようだ。

以前にSURFを実装したNTL MM1では、Bag of FeaturesでSURF特徴量をクラスタリングして用いているが、正規化を行うか否かでクラスタリング結果が変わってくるはずである。ちゃんと検証したわけではないが、直観的に正規化を行わない方がよい結果が得られそうだと思い、このときは論文に合わせて正規化を行わなかった。

ちなみにOpenCV 1.1では次の実装となっている。

vec = (float*)cvGetSeqElem( descriptors, k );
for( kk = 0; kk < (int)(descriptors->elem_size/sizeof(vec[0])); kk++ )
    vec[kk] = 0;

/* 64-bin descriptor */
for( i = 0; i < 4; i++ )
    for( j = 0; j < 4; j++ )
    {
        for( y = i*5; y < i*5+5; y++ )
        {
            for( x = j*5; x < j*5+5; x++ )
            {
                float tx = DX[y][x], ty = DY[y][x];
                vec[0] += tx; vec[1] += ty;
                vec[2] += (float)fabs(tx); vec[3] += (float)fabs(ty);
            }
        }
        double normalize = 0;
        for( kk = 0; kk < 4; kk++ )
            normalize += vec[kk]*vec[kk];
        normalize = 1./(sqrt(normalize) + DBL_EPSILON);
        for( kk = 0; kk < 4; kk++ )
            vec[kk] = (float)(vec[kk]*normalize);
        vec+=4;
    }
}

正規化をピクセル毎に行っており、OpenCV 2.xとは異なった計算式となっている(19-23行)。ピクセル毎に正規化を行うことは、SURFの特性から考えてもあまり良い結果になりそうになく、事実OpenCV 2.0で修正されている。

本来SURFの計算では正規化の必要はなかったが、OpenCVの何らかの都合で正規化の処理が行われているのではないかと思う。OpenCV 1.1の方法は良くなかったんで、2.0から直しておきましたみたいな感じかなぁ。

スポンサーサイト

xrot

みなさんは覚えておいででしょうか?Linuxの黎明期にイケてるゲームを集めたパッケージ「JG」を。この中で最もCoolなゲーム[要出典]の一つに、ここでご紹介する「xrot」がありました。

xrotは、当時のUNIXワークステーション/PC Unix環境に合わせてプログラムの最適化を行っていたことからPseudoColor(256色モード)でしか動作しませんでした。(MIT-Shared Memory Extensionを使うなど、かなり頑張っていた)

初リリースから十数年の時を経て、TrueColorに対応させた最新のxrotをここにリリースします!


xrotのプレイ動画を作成してみました。

 

ソースコードは下記に置いています。(古いスタイルのC(ANSI-Cでない)で作られています)
https://github.com/msiro/xrot

動作確認は、OSX 10.10.3+Xcode 6.3.1 と Ubuntu 15.04 で行いました。

Buildのポイントを下記にまとめておきます。

OSX
Ubuntu
  • 次のパッケージをインストールする。
      xutils-dev, libx11-dev, libxpm-dev, libxext-dev
  • FONTが見つからないエラーとなるため、FONTの定義を変える。
    xwin.c  Line.51-53
    ▼変更前
    #define FONT   "-*-new century schoolbook-medium-i-*--18-*-*-*-p-*-*-*"
    #define FONT_CS   "-*-new century schoolbook-medium-r-*--18-*-*-*-p-*-*-*"
    #define FONT2  "-*-times-bold-r-*--14-*-*-*-p-*-*-*"
    ▼変更後
    #define FONT   "fixed"
    #define FONT_CS   "fixed"
    #define FONT2  "fixed"
    適切なFONT指定方法が見つからなかったためfixedで代用

Enjoy!

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。