在OpenCV里使用特征匹配

特征匹配(Feature Matching)

前面我们花费了大量时间来学习特征检测和描述,其实主要的目的就是为了图像是否匹配的问题。在OpenCV里提供了两个匹配技术:Brute-Force和FLANN。

 

Brute-Force匹配算法是比较简单的,它首先从一个特征集合里取一个特征与另外一个特征集合里每个特征进行比较,如果发现最接近的特征就返回。要使用BF匹配,得用cv.BFMatcher()函数创建BFMatcher对象,创建对象时有两个可选的参数,第一个是normType,指明了怎么样度量距离,默认是cv.NORM_L2,比较适合SIFT和SURF等算法。对于二值字符串的算法ORB、BRIEF、BRISK等,应该使用 cv.NORM_HAMMING,使用Hamming距离来度量。如果ORB算法中WTA_K == 3 或 4,这是要使用 cv.NORM_HAMMING2参数。

 

第二个参数是布尔变量,crossCheck ,默认值是false。如果设置为true时,匹配成功时返回值value(i,j)表示A中第i个特征与B中第j个特征匹配。也就是说,两个集合中的两个特性应该相互匹配。它提供了一致的结果,是d.lowe在sift论文中提出的比率测试的一个很好的替代品。

 

当创建成功之后,就可以使用BFMatcher.match() 和 BFMatcher.knnMatch()函数来返回比较值,第一个函数返回最佳匹配结果,第二个函数返回前k个最好匹配结果。可以使用 cv.drawKeypoints()来显示关键点,cv.drawMatches()来显示匹配点,它是把两个图片水平放在一起,然后从一幅图像画到另一幅图像。有

sift特征点匹配筛选问题

02-19

筛选出了一部分匹配结果,怎么用这些线段把用到的特征点提出来,我想做一个包围盒,谢谢谢谢 ![图片说明](https://img-ask.csdn.net/upload/201602/19/1455858748_415350.jpg) int main(int argc,char* argv[]) { Mat img_1=imread("cap.jpg",CV_LOAD_IMAGE_GRAYSCALE);//宏定义时CV_LOAD_IMAGE_GRAYSCALE=0,也就是读取灰度图像 Mat img_2=imread("capman.jpg",CV_LOAD_IMAGE_GRAYSCALE);//一定要记得这里路径的斜线方向,这与Matlab里面是相反的 if(!img_1.data || !img_2.data)//如果数据为空 { cout<<"opencv error"<<endl; return -1; } cout<<"open right"<<endl; // 第一步,用SIFT算子检测关键点 SiftFeatureDetector detector;//构造函数采用内部默认的 std::vector<KeyPoint> keypoints_1,keypoints_2;//构造2个专门由点组成的点向量用来存储特征点 detector.detect(img_1,keypoints_1);//将img_1图像中检测到的特征点存储起来放在keypoints_1中 detector.detect(img_2,keypoints_2);//同理 //在图像中画出特征点 Mat img_keypoints_1,img_keypoints_2; drawKeypoints(img_1,keypoints_1,img_keypoints_1,Scalar::all(-1),DrawMatchesFlags::DEFAULT);//在内存中画出特征点 drawKeypoints(img_2,keypoints_2,img_keypoints_2,Scalar::all(-1),DrawMatchesFlags::DEFAULT); imshow("sift_keypoints_1",img_keypoints_1);//显示特征点 imshow("sift_keypoints_2",img_keypoints_2); //计算特征向量 SiftDescriptorExtractor extractor;//定义描述子对象 Mat descriptors_1,descriptors_2;//存放特征向量的矩阵 extractor.compute(img_1,keypoints_1,descriptors_1);//计算特征向量 extractor.compute(img_2,keypoints_2,descriptors_2); //用burte force进行匹配特征向量 BruteForceMatcher<L2<float>>matcher;//定义一个burte force matcher对象 vector<DMatch>matches; matcher.match(descriptors_1,descriptors_2,matches); //提取出前15个最佳匹配结果 std::nth_element(matches.begin(), //匹配器算子的初始位置 matches.begin()+14, // 排序的数量 matches.end()); // 结束位置 //剔除掉其余的匹配结果 matches.erase(matches.begin()+15, matches.end()); //绘制匹配线段 Mat img_matches; drawMatches(img_1,keypoints_1,img_2,keypoints_2,matches,img_matches);//将匹配出来的结果放入内存img_matches中 //显示匹配线段 imshow("sift_Matches",img_matches);//显示的标题为Matches //保存 IplImage imgTmp = img_matches; IplImage *input = cvCloneImage(&imgTmp); cvSaveImage("E:\\123.jpg",input ); waitKey(0); return 0; } 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览

应支付9.90元
点击重新获取
扫码支付

支付成功即可阅读