OpenCV学习之旅9——特征检测与匹配(2)
2018-02-20 20:08
387 查看
1. SURF特征提取
在OpenCV中,使用SURF进行特征点描述主要是使用drawMatches 方法和BruteForceMatcher类。1.1 drawMatches()函数
drawMatches用于绘制出相匹配的两个图像的关键点,该函数有两个函数原型。void drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1, const Mat& img2, const vector<KeyPoint>& keypoints2, const vector<DMatch>& matches1to2, Mat& outImg, const Scalar& singlePointColor=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT ); void drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1, const Mat& img2, const vector<KeyPoint>& keypoints2, Mat& outImg, const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1), const vector<vector<char> >& matchesMask=vector<vector<char> >(), int flags=DrawMatchesFlags::DEFAULT );
第一个参数:第一幅源图像;
第二个参数:第一幅图像的特征点,为输出参数;
第三个参数:第二幅源图像;
第四个参数:第二幅图像的特征点,为输出参数;
第五个参数:matches1to2,第一幅图像到第二幅图像的匹配点;
第六个参数:输出图像;
第七个参数:线和关键点的颜色,默认Scalar::all(-1)表随机颜色;
第八个参数:单一特征点的颜色,默认值表随机颜色;
第九个参数:确定哪些匹配是要绘制出来的掩码,默认值表所有的都要绘制;
第十个参数:特征绘制的标识符。
1.2 BruteForceMatches类
template<class Distance> class CV_EXPORTS BruteForceMatcher : public BFMatcher { public: BruteForceMatcher( Distance d = Distance() ) : BFMatcher(Distance::normType, false) {(void)d;} virtual ~BruteForceMatcher() {} };
1.3 程序实例
#include "opencv2/core/core.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/highgui/highgui.hpp" #include <opencv2/nonfree/nonfree.hpp> #include<opencv2/legacy/legacy.hpp> #include <iostream> using namespace cv; using namespace std; //-----------------------------------【main( )函数】-------------------------------------------- // 描述:控制台应用程序的入口函数,我们的程序从这里开始执行 //----------------------------------------------------------------------------------------------- int main( ) { //【0】改变console字体颜色 system("color 1F"); //【1】载入素材图 Mat srcImage1 = imread("1.jpg",1); Mat srcImage2 = imread("2.jpg",1); if( !srcImage1.data || !srcImage2.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; } //【2】使用SURF算子检测关键点 int minHessian = 700;//SURF算法中的hessian阈值 SurfFeatureDetector detector( minHessian );//定义一个SurfFeatureDetector(SURF) 特征检测类对象 std::vector<KeyPoint> keyPoint1, keyPoints2;//vector模板类,存放任意类型的动态数组 //【3】调用detect函数检测出SURF特征关键点,保存在vector容器中 detector.detect( srcImage1, keyPoint1 ); detector.detect( srcImage2, keyPoints2 ); //【4】计算描述符(特征向量) SurfDescriptorExtractor extractor; Mat descriptors1, descriptors2; extractor.compute( srcImage1, keyPoint1, descriptors1 ); extractor.compute( srcImage2, keyPoints2, descriptors2 ); //【5】使用BruteForce进行匹配 // 实例化一个匹配器 BruteForceMatcher< L2<float> > matcher; std::vector< DMatch > matches; //匹配两幅图中的描述子(descriptors) matcher.match( descriptors1, descriptors2, matches ); //【6】绘制从两个图像中匹配出的关键点 Mat imgMatches; drawMatches( srcImage1, keyPoint1, srcImage2, keyPoints2, matches, imgMatches );//进行绘制 //【7】显示效果图 imshow("匹配图", imgMatches ); waitKey(0); return 0; }
2.使用FLANN进行特征点匹配
FLANN——快速最近邻逼近搜索函数库,Fast Libray for Approximate Nearest Neighbors。2.1 FlannBasedMatcher类
class CV_EXPORTS_W FlannBasedMatcher : public DescriptorMatcher { // }
2.2 找到最佳匹配:DescriptorMatcher::match方法
2.3 程序实例
#include "opencv2/core/core.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/highgui/highgui.hpp" #include <opencv2/nonfree/nonfree.hpp> #include<opencv2/legacy/legacy.hpp> #include <iostream> using namespace cv; using namespace std; //-----------------------------------【main( )函数】-------------------------------------------- // 描述:控制台应用程序的入口函数,我们的程序从这里开始执行 //----------------------------------------------------------------------------------------------- int main( int argc, char** argv ) { //【0】改变console字体颜色 system("color 4F"); //【1】载入源图片 Mat img_1 = imread("1.jpg", 1 ); Mat img_2 = imread( "2.jpg", 1 ); if( !img_1.data || !img_2.data ) { printf("读取图片image0错误~! \n"); return false; } //【2】利用SURF检测器检测的关键点 int minHessian = 300; SURF detector( minHessian ); std::vector<KeyPoint> keypoints_1, keypoints_2; detector.detect( img_1, keypoints_1 ); detector.detect( img_2, keypoints_2 ); //【3】计算描述符(特征向量) SURF extractor; Mat descriptors_1, descriptors_2; extractor.compute( img_1, keypoints_1, descriptors_1 ); extractor.compute( img_2, keypoints_2, descriptors_2 ); //【4】采用FLANN算法匹配描述符向量 FlannBasedMatcher matcher; std::vector< DMatch > matches; matcher.match( descriptors_1, descriptors_2, matches ); double max_dist = 0; double min_dist = 100; //【5】快速计算关键点之间的最大和最小距离 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; } //输出距离信息 printf("> 最大距离(Max dist) : %f \n", max_dist ); printf("> 最小距离(Min dist) : %f \n", min_dist ); //【6】存下符合条件的匹配结果(即其距离小于2* min_dist的),使用radiusMatch同样可行 std::vector< DMatch > good_matches; for( int i = 0; i < descriptors_1.rows; i++ ) { if( matches[i].distance < 2*min_dist ) { good_matches.push_back( matches[i]); } } //【7】绘制出符合条件的匹配点 Mat img_matches; drawMatches( img_1, keypoints_1, img_2, keypoints_2, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); //【8】输出相关匹配点信息 for( int i = 0; i < good_matches.size(); i++ ) { printf( ">符合条件的匹配点 [%d] 特征点1: %d -- 特征点2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); } //【9】显示效果图 imshow( "匹配效果图", img_matches ); //按任意键退出程序 waitKey(0); return 0; }
相关文章推荐
- OpenCV中feature2D学习——FAST特征点检测与SIFT/SURF/BRIEF特征提取与匹配
- OpenCV中特征检测,提取与匹配使用方法学习
- OpenCV学习笔记__特征检测与匹配之 SURF算法
- OpenCV学习之旅9——特征检测与匹配(2)
- OpenCV学习之旅9——特征检测与匹配(3)
- opencv学习之 特征检测与匹配
- OpenCV中特征检测,提取与匹配使用方法学习
- OpenCV学习之旅9——特征检测与匹配(1)
- OpenCV学习笔记(29)KAZE 算法原理与源码分析(三)特征检测与描述
- OpenCV--特征点检测与图像匹配
- opencv3.1.0 特征点检测与图像匹配(features2d、xfeatures2d)
- OpenCV成长之路(9):特征点检测与图像匹配
- opencv特征检测与匹配
- 【OpenCV学习笔记】三十、轮廓特征属性及应用(七)—位置关系及轮廓匹配
- OpenCV学习笔记(四十六)——FAST特征点检测features2D OpenCV学习笔记(四十七)——VideoWriter生成视频流highgui OpenCV学习笔记(四十八)——PCA算
- OpenCV成长之路(9):特征点检测与图像匹配
- 学习OpenCV——Fast检测与Surf&Brief匹配(娱乐)
- OPENCV的学习:图像特征检测之Harris角点算法
- OpenCV成长之路(9):特征点检测与图像匹配
- OpenCV之feature2d 模块. 2D特征框架(2)特征描述 使用FLANN进行特征点匹配 使用二维特征点(Features2D)和单映射(Homography)寻找已知物体 平面物体检测