官方文档
参考博文 图像局部特征点检测算法综述
SIFT 特征点提取
图像特征点提取
特征点检测需要用到 OpenCV扩展包。
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
(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;
}
运行结果如下: