OpenCV SIFT特征算法详解与使用

OpenCV SIFT特征算法详解与使用,第1张

OpenCV4.4版本以后已经把SIFT跟SURF特征提取又重新get回来了,可以不需要编译OpenCV源码,直接下载官方预编译版本的就可以直接使用了。但是很多人还以为必须要编译源码才能使用SIFT特征检测的函数!如果还不知道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:" << keypoints_obj.size() << std::endl;
std::cout << "scene keypoints:" << keypoints_sence.size() << std::endl;

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

OpenCV SIFT特征算法详解与使用,2dbd114c-1554-11ed-ba43-dac502259ad0.png,第2张

02

特征描述子匹配

从图像到特征,是特征提取关键 *** 作,特征描述子本质上是一系列的向量数据,它可以唯一表示一张图像。对相似的特征进行区域匹配或者搜索,找到高度相似数据特征片段是特征匹配的主要工作。OpenCV中支持两种特征匹配方法,分别是暴力匹配与FLANN匹配,对浮点数的特征描述子,FLANN匹配比暴力会明显加快运算,创建FLANN实现匹配,并根据相似度排序,寻找最佳匹配得的代码如下:

// 初始化flann匹配
vector matches;
Ptr matcher = FlannBasedMatcher::create();
matcher->match(descriptors_box, descriptors_sence, matches);

// 发现高质量匹配
std::cout << "total matches:" << matches.size() <

运行结果如下:

OpenCV SIFT特征算法详解与使用,2dceb186-1554-11ed-ba43-dac502259ad0.png,第3张

03

单应性矩阵求解与透视变换

这里不再赘述,这部分的代码实现如下:

// 抽取匹配描述子对应的关键点
std::vector obj_pts;
std::vector scene_pts;
for (size_t i = 0; i < matches.size(); 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 < scene_corners.size(); 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);

编辑:黄飞

 

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/dianzi/3001198.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-27
下一篇 2022-09-27

发表评论

登录后才能评论

评论列表(0条)

保存