BFMatcher knnMatch

4
我尝试使用BFMatcher实现knnMatch,代码如下:
BFMatcher matcher(NORM_L2, true);
vector<DMatch> matches;
//matcher.match(descriptors1, descriptors2, matches);
matcher.knnMatch(descriptors1, descriptors2, matches, 2);

并且收到以下错误提示:

fiducialMain.cpp: In function ‘void fiducialCalc(cv::Mat, cv::Mat, cv::Mat&, cv::Mat&, int&)’:
fiducialMain.cpp:98:56: error: no matching function for call to ‘cv::BFMatcher::knnMatch(cv::Mat&, cv::Mat&, std::vector<cv::DMatch>&, int)’
  matcher.knnMatch(descriptors1, descriptors2, matches,2);
                                                        ^
fiducialMain.cpp:98:56: note: candidates are:
In file included from fiducialMain.cpp:15:0:
/usr/local/include/opencv2/features2d/features2d.hpp:1116:18: note: void cv::DescriptorMatcher::knnMatch(const cv::Mat&, const cv::Mat&, std::vector<std::vector<cv::DMatch> >&, int, const cv::Mat&, bool) const
     CV_WRAP void knnMatch( const Mat& queryDescriptors, const Mat& trainDescriptors,
                  ^
/usr/local/include/opencv2/features2d/features2d.hpp:1116:18: note:   no known conversion for argument 3 from ‘std::vector<cv::DMatch>’ to ‘std::vector<std::vector<cv::DMatch> >&’
/usr/local/include/opencv2/features2d/features2d.hpp:1130:18: note: void cv::DescriptorMatcher::knnMatch(const cv::Mat&, std::vector<std::vector<cv::DMatch> >&, int, const std::vector<cv::Mat>&, bool)
     CV_WRAP void knnMatch( const Mat& queryDescriptors, CV_OUT vector<vector<DMatch> >& matches, int k,
                  ^
/usr/local/include/opencv2/features2d/features2d.hpp:1130:18: note:   no known conversion for argument 2 from ‘cv::Mat’ to ‘std::vector<std::vector<cv::DMatch> >&’

请问有人能解释一下这个错误吗?

2个回答

9
请再次查看文档
普通的匹配函数返回一个vector<DMatch>作为结果,而knnMatch(发音:k-nearest-neighbours!)将产生多个(k)向量,因此您需要一个: vector< vector< DMatch > > matches 作为结果。

1
嘿,我猜那是一个非常普遍的陷阱!(你并不是唯一一个遇到这个问题的人) - berak
很遗憾,drawMatches函数不能与vector < vector <DMatch> >一起运行,因为根据文档(http://docs.opencv.org/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html),它只调用单个向量。 - P3d0r
真的,你必须迭代它(或只取第一个)。如果我可以问一下:为什么你需要一个knnMatch(而不是常规匹配)? - berak
简短回答 - 我试图使用knnMatch找到最佳匹配,因为我在使用good_matches算法时遇到了错误问题(https://dev59.com/DIjca4cB1Zd3GeqPtTdI?noredirect=1#comment45759998_28725273)。也许不是最好的方法,但我正在进行实验。 - P3d0r

4

你对BFMatcher的参数设置有误。当你将crossCheck设为true时,每个关键点只能匹配一个特征点。然而,在使用knnMatch时,你需要有多个匹配项。因此,你的代码应该像这样:

BFMatcher matcher(NORM_L2);
std::vector<vector<DMatch> > matches;
matcher.knnMatch(descriptors1, descriptors2, matches,2);

std::vector<DMatch> match1;
std::vector<DMatch> match2;

for(int i=0; i<matches.size(); i++)
{
    match1.push_back(matches[i][0]);
    match2.push_back(matches[i][1]);
}

Mat img_matches1, img_matches2;
drawMatches(img1, kp1, img2, kp2, match1, img_matches1);
drawMatches(img1, kp1, img2, kp2, match2, img_matches2);

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