opencv4 图像特征匹配_OpenCV4.4 中SIFT特征匹配调用演示

点击上方蓝字关注我们
微信公众号:OpenCV学堂
关注获取更多计算机视觉与深度学习知识
大家好,听说OpenCV4.4 已经把SIFT跟SURF特征提取又重新get回来了,可以不需要编译OpenCV源码,直接下载官方预编译版本的就可以直接使用了。如果你还不知道SIFT特征是什么,就看这里的这篇文章就好啦。
OpenCV SIFT特征算法详解与使用
01
创建SIFT特征提取器
下面就来验证一下是否真的可以了,请看步骤与过程,首先创建SIFT特征提取器,实现特征点跟描述子的提取,代码实现如下:
// 创建SIFT特征提取auto detector = SIFT::create();vector keypoints_obj, keypoints_sence;Mat descriptors_box, descriptors_sence;detector->detectAndCompute(box, Mat(), keypoints_obj, descriptors_box);detector->detectAndCompute(scene, Mat(), keypoints_sence, descriptors_sence);std::cout <"box keypoints:" <std::endl;std::cout <"scene keypoints:" <std::endl;
运行打印出来的关键点数目分别如下:

02
特征描述子匹配
从图像到特征,是特征提取关键操作,特征描述子本质上是一系列的向量数据,它可以唯一表示一张图像。对相似的特征进行区域匹配或者搜索,找到高度相似数据特征片段是特征匹配的主要工作。OpenCV中支持两种特征匹配方法,分别是暴力匹配与FLANN匹配,对浮点数的特征描述子,FLANN匹配比暴力会明显加快运算,创建FLANN实现匹配,并根据相似度排序,寻找最佳匹配得的代码如下:
// 初始化flann匹配vector matches;Ptr matcher = FlannBasedMatcher::create();matcher->match(descriptors_box, descriptors_sence, matches);// 发现高质量匹配std::cout <"total matches:" <std::endl;int numOfGood = matches.size() * 0.15;std::sort(matches.begin(), matches.end());matches.erase(matches.begin() + numOfGood, matches.end());std::cout <"good matches:" <std::endl;Mat dst;drawMatches(box, keypoints_obj, scene, keypoints_sence, matches, dst);imshow("output", dst);imwrite("D:/matches.png", dst);
运行结果如下:

03
单应性矩阵求解与透视变换
对得到的最佳匹配描述子对,取得对应的图像关键点坐标,完成单应性矩阵求解,实现透视变换,是重要的一步,关于单应性矩阵的求解与应用,建议看公众号之前的几篇相关文章即可:
OpenCV单应性矩阵发现参数估算方法详解
单应性矩阵应用-基于特征的图像拼接
利用单应性矩阵实现文档对齐显示
这里不再赘述,这部分的代码实现如下:
// 抽取匹配描述子对应的关键点std::vector obj_pts;std::vector scene_pts;for (size_t i = 0; i { obj_pts.push_back(keypoints_obj[matches[i].queryIdx].pt); scene_pts.push_back(keypoints_sence[matches[i].trainIdx].pt);}// 对象对齐与单应性矩阵求解Mat H = findHomography(obj_pts, scene_pts, RANSAC);std::vector obj_corners(4);obj_corners[0] = Point(0, 0); obj_corners[1] = Point(box.cols, 0);obj_corners[2] = Point(box.cols, box.rows); obj_corners[3] = Point(0, box.rows);std::vector scene_corners(4);perspectiveTransform(obj_corners, scene_corners, H);
04
BOX矩形框绘制
求得最终的位置信息,根据得到四个点坐标通过多边形绘制函数,完成绘制,这个其中有必要重点解释一下多边形绘制函数
void cv::polylines ( InputOutputArray img, InputArrayOfArrays pts, bool isClosed, const Scalar & color, int thickness = 1, int lineType = LINE_8, int shift = 0)
参数解释如下
img表示输入图像
pts表示绘制的多边形顶点集合,必须是int类型CV_32SC
isClosed表示是否闭合
color表示多边形颜色
thickness表示线宽,注意:必须大于等于零,如果想要填充它,请用drawContours
lineType表示对线的渲染方式
shift表示迁移,默认为0。这个在ROI上绘制时候有用
实现代码如下:
// 绘制发现的对象std::vector pts;for (int i = 0; i pts.push_back(scene_corners[i]);}polylines(scene, pts, true, Scalar(0, 0, 255), 2, 8, 0);// 显示匹配对象imshow("Good Matches & Object detection", scene);imwrite("D:/findobject.png", scene);
运行结果如下:

此外我还注意到SURF貌似还不能直接使用,是不是还是要编译扩展模块才可以这个我真的要认真探索一波!欢迎大家留言反馈
善始者实繁
克终者盖寡
推荐阅读
OpenCV4系统化学习路线图-视频版本!
OpenCV单应性矩阵发现参数估算方法详解
单应性矩阵应用-基于特征的图像拼接
OpenCV图像拼接改进算法之完美拼接
OpenCV | 二值图像分析的技巧都在这里
OpenCV二值图像分析之形态学应用技巧
图像色彩空间与应用转换
五分钟学会C++高效图表绘制神器调用
没想到图像直方图有这么多应用场景
基于灰度共生矩阵(GLCM)的图像纹理分析与提取
OpenCV中一个最容易搞错的形态学操作
OpenCV实现皮肤表面粗糙度3D显示
解密 | OpenCV加载图像大小是有限制的 ?
OpenCV中ORB特征提取与匹配
OpenCV SIFT特征算法详解与使用
HOG特征详解与行人检测

