以下是我的代码,用于使用SURF提取特征,并使用flannBasedMatcher匹配点。
Mat object = imread("S6E0.bmp", CV_LOAD_IMAGE_GRAYSCALE);
if( !object.data )
{
// std::cout<< "Error reading object " << std::endl;
return -2;
}
//Detect the keypoints using SURF Detector
int minHessian = 500;
SurfFeatureDetector detector( minHessian );
std::vector<KeyPoint> kp_object;
detector.detect( object, kp_object );
//Calculate descriptors (feature vectors)
SurfDescriptorExtractor extractor;
Mat des_object;
extractor.compute( object, kp_object, des_object );
FlannBasedMatcher matcher;
char key = 'a';
//VideoCapture cap(0);
namedWindow("Good Matches");
std::vector<Point2f> obj_corners(4);
//Get the corners from the object
obj_corners[0] = cvPoint(0,0);
obj_corners[1] = cvPoint( object.cols, 0 );
obj_corners[2] = cvPoint( object.cols, object.rows );
obj_corners[3] = cvPoint( 0, object.rows );
Mat image = imread("S6E0.bmp", CV_LOAD_IMAGE_GRAYSCALE);
Mat des_image, img_matches;
std::vector<KeyPoint> kp_image;
std::vector<vector<DMatch >> matches;
std::vector<std::vector<cv::DMatch>> matches1;
std::vector<std::vector<cv::DMatch>> matches2;
std::vector<cv::DMatch> matches3;
std::vector<DMatch > good_matches;
std::vector<Point2f> obj;
std::vector<Point2f> scene;
std::vector<Point2f> scene_corners(4);
Mat H;
//cvtColor(frame, image, CV_RGB2GRAY);
detector.detect( image, kp_image );
extractor.compute( image, kp_image, des_image );
matcher.knnMatch(des_object, des_image, matches, 2);
for(int i = 0; i < min(des_image.rows-1,(int) matches.size()); i++) //THIS LOOP IS SENSITIVE TO SEGFAULTS
{
if((matches[i][0].distance < 0.6*(matches[i][1].distance)) && ((int) matches[i].size()<=2 && (int) matches[i].size()>0))
{
good_matches.push_back(matches[i][0]);
}
}
//Draw only "good" matches
drawMatches( object, kp_object, image, kp_image, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
if (good_matches.size() >= 4)
{
printf("Images matching %d , %d", good_matches.size(), kp_object.size());
//return 1;
for( int i = 0; i < good_matches.size(); i++ )
{
//Get the keypoints from the good matches
obj.push_back( kp_object[ good_matches[i].queryIdx ].pt );
scene.push_back( kp_image[ good_matches[i].trainIdx ].pt );
}
//H = findHomography( obj, scene, CV_RANSAC );
//printf("Size : %d", H.size());
//perspectiveTransform( obj_corners, scene_corners, H);
//printf("Size : %d --- %d --- %d", H.size(), scene_corners.size());
}else{
printf("Images matching %d , %d", good_matches.size(), kp_object.size());
}
//Show detected matches
imshow( "Good Matches", img_matches );
waitKey(0);
return 0;
在这段代码中,我想知道通过这种方法究竟发生了什么
matcher.knnMatch(des_object, des_image, matches, 2);
据我所知,我传递了匹配图像的两个描述符,匹配向量填充了2个最近邻居。我想知道方法中究竟发生了什么,以及如何填充匹配方法以及填充哪些点。
在此代码段
中for(int i = 0; i < min(des_image.rows-1,(int) matches.size()); i++) //THIS LOOP IS SENSITIVE TO SEGFAULTS
{
if((matches[i][0].distance < 0.6*(matches[i][1].distance)) && ((int) matches[i].size()<=2 && (int) matches[i].size()>0))
{
good_matches.push_back(matches[i][0]);
}
}
我使用最近的neibour距离比(nndr)为0.6,我想知道如何找出good_matches以及nndr值的变化将如何影响。
如果我可以解决此代码,那将是一个很大的帮助。 感谢。
答案 0 :(得分:3)
FlannBasedMatcher 基于Muja et. al.撰写的论文;你可以找到确切的算法以及它们如何在那里进行..
关于 good_matches ,您只是在代码段中看到它是最佳匹配的集合,您的结果基于条件,即 nndr ..它基本上是一个阈值,它决定在完全放弃匹配之前允许匹配的距离。更高的阈值,更多的点被考虑,更多的是正匹配的数量(它们是否是 true positives 是否由您的数据集和设置nndr级别的方式确定.. ..
希望这有帮助。