9

これが私の問題です。複数の画像でSURFを使用してキーポイントの特徴を手動で抽出しました。しかし、私はすでにどのペアのポイントが一致するかを知っています。問題は、一致するペアを作成しようとしているのですが、その方法がわかりません。コードを見てみましたが、めちゃくちゃです。

今のところ、行列であるfeatures.descriptorsのサイズは、キーポイントの数と同じであることがわかっています(他の次元は1です)。コードでは、一致するペアを検出するために、記述子のみを使用しているため、行(または列、わかりません)または2つの記述子マトリックスを比較し、共通点があるかどうかを判断します。

しかし、私の場合、画像1のキーポイントiと画像2のキーポイントjの間に一致があることはすでに知っています。これをMatchesInfo値として説明するにはどうすればよいですか。特に、タイプstd :: vector <cv::DMatch>の要素が一致します。

編集:だから、これのために、私はマッチャーやこのようなものを使用する必要はありません。私はどのペアが一緒に行くのか知っています!

4

1 に答える 1

6

あなたが正しく質問していることを理解した場合、OpenCVで描画したり、同様のOpenCV関数で使用したりstd::vector<cv::DMatch>するために、キーポイントを一致させる必要があると思います。cv::drawMatches最近「手動」でマッチングも行っていたので、元々aに含まれていた任意のマッチを作成し、std::vector<std::pair <int, int> > aMatchesそれらをウィンドウに表示するコードを次に示します。

const cv::Mat& pic1 = img_1_var;
const cv::Mat& pic2 = img_2_var;
const std::vector <cv::KeyPoint> &feats1 = img_1_feats;
const std::vector <cv::KeyPoint> &feats2 = img_2_feats;
    // you of course can work directly with original objects
    // but for drawing you only need const references to
    // images & their corresponding extracted feats

std::vector <std::pair <int, int> > aMatches;
    // fill aMatches manually - one entry is a pair consisting of
    //      (index_in_img_1_feats, index_in_img_2_feats)


// the next code draws the matches:
std::vector <cv::DMatch> matches;
matches.reserve((int)aMatches.size());

for (int i=0; i < (int)aMatches.size(); ++i)
    matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second,
                      std::numeric_limits<float>::max()));

cv::Mat output;

cv::drawMatches(pic1, feats1, pic2, feats2, matches, output);

cv::namedWindow("Match", 0);
cv::setWindowProperty("Match", CV_WINDOW_FULLSCREEN, 1);
cv::imshow("Match", output);    
cv::waitKey();
cv::destroyWindow("Match");

または、描画よりも複雑な目的で一致に関するより完全な情報が必要な場合は、一致間の距離を適切な値に設定することもできます。たとえば、L2距離を使用して距離を計算する場合は、次の行を置き換える必要があります。

for (int i=0; i < (int)aMatches.size(); ++i)
    matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second,
                      std::numeric_limits<float>::max()));

これで(これには、特徴記述子ベクトルへの参照も必要であることに注意してください):

cv::L2<float> cmp;

const std::vector <std::vector <float> > &desc1 = img_1_feats_descriptors;
const std::vector <std::vector <float> > &desc2 = img_2_feats_descriptors;

for (int i=0; i < (int)aMatches.size(); ++i){
    float *firstFeat = &desc1[aMatches[i].first];
    float *secondFeat = &desc2[aMatches[i].second];
    float distance = cmp(firstFeat, secondFeat, firstFeat->size());
    matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second,
                      distance));
}

最後のスニペットでdescX[i]は、がの記述子でfeatsX[i]あり、内部ベクトルの各要素が記述子ベクトルの1つのコンポーネントであることに注意してください。また、すべての記述子ベクトルは同じ次元である必要があることに注意してください。

于 2012-04-10T13:44:57.880 に答える