Advertisement

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

阅读量:
2c822573f24182504917ae8ca9934ddf.gif

点击上方蓝字关注我们

微信公众号: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;

运行打印出来的关键点数目分别如下:
87e0584dd9243f28ca89a0cc350a7b3d.png

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);

运行结果如下:
66a538a7ac4453944ac99f82d98c22f0.png

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);

运行结果如下:
cd87dc3aa895f75b5a8522dd863b33aa.png

此外我还注意到SURF貌似还不能直接使用,是不是还是要编译扩展模块才可以这个我真的要认真探索一波!欢迎大家留言反馈

善始者实繁

克终者盖寡

推荐阅读

OpenCV4系统化学习路线图-视频版本!

OpenCV单应性矩阵发现参数估算方法详解

单应性矩阵应用-基于特征的图像拼接

OpenCV图像拼接改进算法之完美拼接

OpenCV | 二值图像分析的技巧都在这里

OpenCV二值图像分析之形态学应用技巧

图像色彩空间与应用转换

五分钟学会C++高效图表绘制神器调用

没想到图像直方图有这么多应用场景

基于灰度共生矩阵(GLCM)的图像纹理分析与提取

OpenCV中一个最容易搞错的形态学操作

OpenCV实现皮肤表面粗糙度3D显示

解密 | OpenCV加载图像大小是有限制的 ?

OpenCV中ORB特征提取与匹配

OpenCV SIFT特征算法详解与使用

HOG特征详解与行人检测
bc1c2f7b9c1d6c265bdec220541e249b.png

全部评论 (0)

还没有任何评论哟~