OpenCV学习之路(二十四) 特征检测

官方文档

参考博文 图像局部特征点检测算法综述

SIFT 特征点提取

图像特征点提取

特征点检测需要用到 OpenCV扩展包。

 

SURF 算子

OpenCV 中关于 SURF 算法的部分,常常涉及到的是 SURF、SurfFeatureDetector、SurfDescriptorExtractor 这三个类。

typedef SURF SurfFeatureDetector;
typedef SURF SurfDescriptorExtractor;

因此三者其实等价。

1. drawKeyPoints() 函数,绘制关键点。函数原型如下:

void drawKeyPoints(const Mat& image, 
                   const vector<KeyPoint>& keyPoints, 
                   Mat& outImage, 
                   const Scalar& color = Scalar::all(-1), 
                   int flags = DrawMatchesFlags::DEFAULT);

(1)第一个参数,const Mat& 类型的 src,输入图像。

(2)第二个参数,const vector<KeyPoint>& 类型的keypoints,根据原图像检测得到的特征点。

(3)第三个参数,Mat& 类型的 outImage,输出图像,其内容取决于第五个参数标识符 flags。

(4)第四个参数,const Scalar& 类型的 color,关键点的颜色,默认值为 Scalar::all(-1)。

(5)第五个参数,int 类型的 flags,绘制关键点的特征标识符,默认值为 DrawMatchedFlags::DEFAULT。可以在如下结构体中取值:

struct DrawMatchesFlags
{
    enum
    {
        DEFAULT = 0, //创建输出图像矩阵(使用 Mat::create),使用现存的输出图像绘制匹配对和特征                                                                            
                      点。且对每一个关键点,只绘制中间点
        DRAW_OVER_OOUTIMG = 1, //不创建输出图像矩阵,而是在输出图像上绘制匹配对
        NOT_DRAW_SINGLE_POINTS = 2, //单点特诊点不被绘制
        DRAW_RICH_KEYPOINTS = 4, //对每一个关键点,绘制带大小和方向的关键点圆圈
    };
};

 keyPoint 类,用于表示特征点的数据结构。如下所示:

class KeyPoint
{
    Point2f pt; //坐标
    float size; //特征点邻域直径
    float angle; //特征点的方向,值为 [0,360],负值表示不适用
    float response; 
    int octave; //特征点所在的图像金字塔的组
    int class_id; //用于聚类的 id
}

 

2.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& matchColor = Scalar::all(-1), 
                 const Scalar& singlePointColor = Scalar::all(-1), 
                 const vector<char>& matchesMask = vector<char>(), 
                 int flags = DrawMatchesFlags::DEFAULT);

(1)第一个参数,第一幅源图像。

(2)第二个参数,第一幅源图像检测到的特征点集合。

(3)第三个参数,第二幅源图像。

(4)第四个参数,第二幅源图像检测到的特征点集合。

(5)第五个参数,第一幅图像到第二幅图像的匹配点。即表示图1中的特征点在图2中有对应的匹配点。

(6)第六个参数,输出图像,其内容取决于第十个参数 flags。

(7)第七个参数,匹配的输出颜色,即线和匹配点的颜色。默认值为 Scalar::all(-1),表示颜色是随机生成的。

(8)第八个参数,单一特征点的颜色,默认值为 Scalar::all(-1)。

(9)第九个参数, matchesMask,确定哪些匹配是会绘制出来的掩膜,默认值为空,表示所有的都绘制。

(10 第十个参数,int 类型的 flags,特征绘制的标识符。参考 drawKeyPoints() 函数参数说明。

 

简单示例代码如下:

#include<stdio.h>
#include<iostream>
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/xfeatures2d.hpp"

using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;

int main()
{
	Mat srcSurfImg1 = imread("graf1.png");
	Mat srcSurfImg2 = imread("graf3.png");

	//使用 SURF 算子进行检测关键点
	int minHessian = 1000; //SURF 算法中的 hessian 阈值

	Ptr<SURF> detector = SURF::create();
	detector->setHessianThreshold(minHessian);

	// 检测特征点,并计算特征向量
	vector<KeyPoint> keyPoints1, keyPoints2;
	Mat descriptors1, descriptors2;
	detector->detectAndCompute(srcSurfImg1, Mat(), keyPoints1, descriptors1);
	detector->detectAndCompute(srcSurfImg2, Mat(), keyPoints2, descriptors2);

	//使用 BruteForce 进行匹配
	BFMatcher matcher(NORM_L2);
	vector<DMatch> matches;
	matcher.match(descriptors1, descriptors2, matches);

	//绘制匹配出的关键点
	Mat dstMatchImg;
	drawMatches(srcSurfImg1, keyPoints1, srcSurfImg2, keyPoints2, matches, dstMatchImg);

	imshow("效果图", dstMatchImg);

	waitKey(0);
	return 0;
}

运行结果如下:


 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值