您的位置:首页 > 运维架构

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

2015-03-18 10:44 381 查看

BruteForceMatcher与FlannBasedMatcher

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
​       代码如下(参考http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.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),详情请看下一章。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv2 图像特征