Page List

Search on the blog

2014年5月3日土曜日

OpenCV日記(12)Dense Sampling

 SURFを使うと、画像の中から特徴的な領域をkeypointとして抽出することが出来る。このkeypointを使うと、異なる視点から同一の物体を見たときにどの点がどの点に対応しているかというマッピングを調べることが出来る。よって複数の写真をつなげてパノラマ写真を作りたいというような用途には適している。

 しかし、SURFが抽出したkeypointを使って画像識別を行いたい場合は以下のようにいくつかの問題がある。
  • 画像から抽出されるkeypointの数は一定でない。
  • 統計処理を行うのに必要な数のkeypointが選ばれないことがある。
  • コントラストが小さい画像の場合keypointが一つも選ばれないこともある。
ということで、あらかじめ決めておいたグリッド上の点をkeypointとして選ぶdense samplingという手法がよく使われるらしい。dense samplingで選んだ点に対してSURFでdescriptorを計算するということをやってみた。

ソースコード
#include <stdio.h>
#include <iostream>

#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"

using namespace cv;

static void help() 
{
    printf("Usage:\n dense_sample <image> \n");
}

int main(int argc, char** argv)
{
    if(argc != 2)
    {
        help();
        return -1;
    }

    Mat img = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);

    if(img.empty())
    {
        printf("Can't read an image.x\n");
        return -1;
    }

    DenseFeatureDetector detector(
        4.0,    // initFeatureScale (keypoints' diameter)
        2,      // featureScaleLevels (how many time apply detector with changing image scale)
        0.5,    // featureScaleMul (scale factor)
        1,      // initXyStep (distance between two keypoints)
        0,      // initImgBound (start axis of keypoints)
        false,  // varyXyStepWithScale
        false   // varyImgBoundWithScale
    );

    // detecting keypoints
    vector<KeyPoint> keypoints;
    detector.detect(img, keypoints);
    
    // computing descriptors
    SurfDescriptorExtractor extractor;
    Mat descriptors;
    extractor.compute(img, keypoints, descriptors);

    // show info
    std::cout << "keypoints of img: " << keypoints.size() << std::endl;
    std::cout << "descriptors of img: " << descriptors.size() << std::endl;

    return 0;
}
メモ書き
DenseFeatureDetectorというOpenCVのクラスを使うと簡単にdense samplingが出来た。keypointの半径が何を意味しているのかよく分かっていない。勾配ベクトルのヒストグラムを計算するときの領域サイズとかだろうか??SURFのアルゴリズムをもう少し詳しく調べないといけない気がする。

とりあえず、これで同じサイズの画像からは同じサイズの特徴ベクトルを抽出できるようになった。descriptorをクラスタリングして、各クラスタに属するdescriptorの数をヒストグラムで表したものを特徴量として扱う手法が有名みたいなので今度はそれをやってみようと思う。

0 件のコメント:

コメントを投稿