9

这是我的问题。我在多张图像上使用 SURF 手动提取关键点特征。但我也已经知道哪一对点会匹配。问题是,我正在尝试创建我的配对,但我不明白如何。我试图通过查看代码,但它是一团糟。

现在,我知道 features.descriptors 的大小,一个矩阵,与关键点的个数相同(另一个维度是 1)。在代码中,为了检测匹配对,它只使用描述符,所以它比较行(或列,我不确定)或两个描述符矩阵,并确定是否有任何共同点。

但就我而言,我已经知道图像 1 中的关键点 i 和图像 2 中的关键点 j 之间存在匹配。我如何将其描述为 MatchesInfo 值。特别是 std::vector< cv::DMatch > 类型的元素匹配。

编辑:所以,为此,我不需要使用任何匹配器或类似的东西。我知道哪对会在一起!

4

1 回答 1

6

如果我正确理解您的问题,我假设您希望关键点匹配以std::vector<cv::DMatch>使用 OpenCV 绘制它们cv::drawMatches或使用一些类似的 OpenCV 函数。由于我最近也在“手动”进行匹配,所以这是我的代码,它绘制了最初包含在 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],内部向量的每个元素都是描述符向量的一个组成部分。另外,请注意所有描述符向量应该具有相同的维度。

于 2012-04-10T13:44:57.880 回答