在OpenCV中,手动从特征关键点进行配对匹配

9
这是我的问题。我在多张图像上使用SURF手动提取了关键点特征。但我已经知道哪些点对将会匹配。问题是,我正在尝试创建我的匹配对,但我不明白如何操作。我试着查看代码,但它很混乱。
现在,我知道特征描述符(一个矩阵)的大小与关键点数相同(另一个维度为1)。在代码中,为了检测匹配对,只使用描述符,因此它比较两个描述符矩阵的行或列(我不确定),并确定是否存在共同之处。
但在我的情况下,我已经知道来自图像1的关键点i和来自图像2的关键点j之间有一次匹配。我该如何将其描述为MatchesInfo值,尤其是matches元素,类型为std :: vector 。
编辑:所以,对于这个问题,我不需要使用任何匹配器或类似的东西。我知道哪些配对彼此匹配!

为了以后参考,请尽量让你的问题更清晰明了。我基于“我知道哪些配对在一起”和“std::vectorcv::DMatch”来提供示例。如果您需要任何额外的答案澄清,请尝试用更精确的问题描述。 - penelope
1个回答

6
如果我正确理解您的问题,我认为您想要在std::vector<cv::DMatch>中获取关键点匹配项,以便将其与OpenCV cv::drawMatches一起绘制或在类似的OpenCV函数中使用。由于我最近也正在手动进行匹配,这是我的代码,它可以绘制最初包含在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]的描述符,内部向量的每个元素都是描述符向量的一个组成部分。此外,请注意,所有描述符向量应具有相同的维度。

我的描述符是cv::Mat类型的,我该如何将它们转换为vector<vector<float>>?或者它们可以自然地转换吗? - widgg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接