SLAM14讲 第七章 特征点法
Posted lingting0919
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SLAM14讲 第七章 特征点法相关的知识,希望对你有一定的参考价值。
SIFT尺度不变特征变换 5228.7ms
FAST关键点——计算速度很快,没有描述子,不具有方向性
ORB(旋转、尺度不变性)——速度极快的二进制描述子BRIEF 1000点/15.3ms
SURF 217.3ms
#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/features2d/features2d.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; int main ( int argc, char** argv ) { if ( argc != 3 ) //确认输入为两张图片 { cout<<"usage: feature_extraction img1 img2"<<endl; return 1; } //-- 读取图像 // imread C++ 模型 // include <opencv2/imgcodecs.hpp> // Mat cv::imread( const String & filename, int flags = IMREAD_COLOR) // 返回MAT类型,读取失败时返回空矩阵 Mat::data = NULL // 参数1:filename 读取的图片文件名 绝对/相对路径 要加后缀 // 参数2:flags 读取标记,读取图片的方式,默认为IMREAD_COLOR(好像没影响) Mat img_1 = imread ( argv[1], IMREAD_COLOR ); Mat img_2 = imread ( argv[2], CV_LOAD_IMAGE_COLOR ); //-- 初始化 std::vector<KeyPoint> keypoints_1, keypoints_2;//关键点-放置keypoint对象的一个vector Mat descriptors_1, descriptors_2;//描述子,cv::Mat类型 //OpenCV提供FeatureDetector实现特征检测及匹配; //FeatureDetetor是虚类,通过定义FeatureDetector的对象可以使用多种特征检测方法。通过create()函数调用: //FASTSTARSIFTSURFORBMSERGFTTHARRISDenseSimpleBlob Ptr<FeatureDetector> detector = ORB::create();//ORB特征点检测 Ptr<DescriptorExtractor> descriptor = ORB::create();//BRIEF描述子提取 //计算特征点之间的描述子距离,通常汉明距离 //DescriptorMatcher是匹配特征向量的抽象类,在OpenCV2中的特征匹配方法都继承自该类 //(例如:BFmatcher,FlannBasedMatcher)。该类主要包含了两组匹配方法:图像对之间的匹配以及图像和一个图像集之间的匹配 //DescriptorMatcher::create 对于给定参数,创建特征描述子匹配(使用默认的构造函数). //BruteForce(L2)、BruteForce-L1BruteForce-HammingBruteForce-HammingLUTFlannBased Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create ( "BruteForce-Hamming" ); //-- 第一步:检测 Oriented FAST 角点位置 detector->detect ( img_1,keypoints_1 ); detector->detect ( img_2,keypoints_2 ); //-- 第二步:根据角点位置计算 BRIEF 描述子 descriptor->compute ( img_1, keypoints_1, descriptors_1 ); descriptor->compute ( img_2, keypoints_2, descriptors_2 ); Mat outimg1; drawKeypoints( img_1, keypoints_1, outimg1, Scalar::all(-1), DrawMatchesFlags::DEFAULT ); imshow("图1 ORB特征点",outimg1); Mat outimg2; drawKeypoints( img_2, keypoints_2, outimg2, Scalar::all(-1), DrawMatchesFlags::DEFAULT ); imshow("图2 ORB特征点",outimg2); //-- 第三步:对两幅图像中的BRIEF描述子进行匹配,使用 Hamming 距离 //DMatch是用于匹配特征关键点的特征描述子的类:查询特征描述子索引, 特征描述子索引, 训练图像索引, 以及不同特征描述子之间的距离. vector<DMatch> matches; //BFMatcher matcher ( NORM_HAMMING ); matcher->match ( descriptors_1, descriptors_2, matches ); //-- 第四步:匹配点对筛选 double min_dist=10000, max_dist=0; //找出所有匹配之间的最小距离和最大距离, 即是最相似的和最不相似的两组点之间的距离 for ( int i = 0; i < descriptors_1.rows; i++ ) { double dist = matches[i].distance; if ( dist < min_dist ) min_dist = dist; if ( dist > max_dist ) max_dist = dist; } // 仅供娱乐的写法 min_dist = min_element( matches.begin(), matches.end(), [](const DMatch& m1, const DMatch& m2) {return m1.distance<m2.distance;} )->distance; max_dist = max_element( matches.begin(), matches.end(), [](const DMatch& m1, const DMatch& m2) {return m1.distance<m2.distance;} )->distance; printf ( "-- Max dist : %f ", max_dist ); printf ( "-- Min dist : %f ", min_dist ); //当描述子之间的距离大于两倍的最小距离时,即认为匹配有误.但有时候最小距离会非常小,设置一个经验值30作为下限. std::vector< DMatch > good_matches; for ( int i = 0; i < descriptors_1.rows; i++ ) { if ( matches[i].distance <= max ( 2*min_dist, 30.0 )) { good_matches.push_back ( matches[i] ); } } //-- 第五步:绘制匹配结果 Mat img_match; Mat img_goodmatch; drawMatches ( img_1, keypoints_1, img_2, keypoints_2, matches, img_match ); drawMatches ( img_1, keypoints_1, img_2, keypoints_2, good_matches, img_goodmatch ); imshow ( "图3 所有匹配点对", img_match ); imshow ( "图4 优化后匹配点对-筛选小于两倍最小汉明距离或工程经验值30的点", img_goodmatch ); imwrite ( "图3 所有匹配点对.png", img_match ); imwrite ( "图4 优化后匹配点对筛选小于两倍最小汉明距离或工程经验值30的点.png", img_goodmatch ); waitKey(0);
max-dist:95
min-dist:4
所有匹配点对:
优化后匹配点对(小于两倍最小汉明距离的点):
优化后匹配点对(小于两倍最小汉明距离或工程经验值30的点):
优化后匹配点对(小于最小和最大汉明距离中间值的点):
以上是关于SLAM14讲 第七章 特征点法的主要内容,如果未能解决你的问题,请参考以下文章