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

官方文档

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

SIFT 特征点提取

图像特征点提取

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

 

SURF 算子

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

typedef SURF SurfFeatureDetector;
typedef SURF SurfDescriptorExtractor;

因此三者其实等价。

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

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

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

(2)第二个参数,const vector& 类型的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& keypoints1, 
                 const Mat& img2, 
                 const vector& keypoints2, 
                 const vector& matches1to2, 
                 Mat& outImg, 
                 const Scalar& matchColor = Scalar::all(-1), 
                 const Scalar& singlePointColor = Scalar::all(-1), 
                 const vector& matchesMask = vector(), 
                 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
#include
#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 detector = SURF::create();
	detector->setHessianThreshold(minHessian);

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

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

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

	imshow("效果图", dstMatchImg);

	waitKey(0);
	return 0;
}

运行结果如下:


 

 

你可能感兴趣的:(OpenCV,学习)