OpenCV SIFT特征学习 (三) 特征如何更好的匹配(上)

本文深入探讨OpenCV中SIFT特征的匹配方法,重点关注BruteForceMatcher和FlannBasedMatcher的使用,解析如何优化特征匹配过程。
摘要由CSDN通过智能技术生成

BruteForceMatcherFlannBasedMatcher

OpenCV自带的匹配方式主要有两种,蛮力法 BruteForceMatcher与 FlannBasedMatcher
BruteForceMatcher
        匹配时,假设输入两组kyepoints为kp1,kp2,则按顺序kp1的点与kp2中的匹配,距离最近的即为匹配点,故匹配结果是产生数量与kp1相同的DMatch。距离的计算有以下方法:L1( 绝对值相加,又称曼哈顿距离 )、L2(欧几里得距离)、Hamming、HammingLUT
FlannBasedMatcher
        首先要理解Flann:FLANN( Fast Approximate Nearest Neighbor Search Library,快速近似最近邻搜索库   ),是一个快速最近邻搜索优化算法的集合,用于大数据集以及高维数据的检索。介绍详见 http://docs.opencv.org/modules/flann/doc/flann_fast_approximate_nearest_neighbor_search.html
  
  
cv::Mat image1=cv::imread("D:\\sift1.bmp");
cv::Mat image2=cv::imread("D:\\sift2.bmp");
cv::Mat out;
cv::SiftFeatureDetector siftdtc;
std::vector<cv::KeyPoint> kp1,kp2;
siftdtc.detect(image1,kp1);
siftdtc.detect(image2,kp2);
//---------------------------------------------------------
SiftDescriptorExtractor extractor;
Mat descriptor1,descriptor2;
Mat img_matches;
extractor.compute(image1,kp1,descriptor1);
extractor.compute(image2,kp2,descriptor2);
 
//-- Step 3: Matching descriptor vectors using FLANN matcher
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptor1, descriptor2, matches );
 
double max_dist = 0; double min_dist = 100;
 
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descriptor1.rows; i++ )
{ double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
 
printf("-- Max dist : %f \n", max_dist );
printf("-- Min dist : %f \n", min_dist );
 
//-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
//-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
//-- small)
//-- PS.- radiusMatch can also be used here.
std::vector< DMatch > good_matches;
 
for( int i = 0; i < descriptor1.rows; i++ )
{ if( matches[i].distance <= max(2*min_dist, 0.02) )
{ good_matches.push_back( matches[i]); }
}
 
//-- Draw only "good" matches
// Mat img_matches;
drawMatches( image1, kp1, image2, kp2,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
 
//-- Show detected matches
imshow( "Good Matches", img_matches );
 
for( int i = 0; i < (int)good_matches.size(); i++ )
{ printf( "-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); }
cv :: waitKey ( 0 );       


由上图得,仍存在不少同名匹配点(即kp1与kp2不是1对1的关系 ),那么如何更好的筛选呢?常用的方法有随记采样一致算法(RANSAC),详情请看下一章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值