SURF算法需要安装额外的扩展模块,安装步骤和注意事项见我博客:https://blog.csdn.net/qq_27396861/article/details/88095820
SURF::create() 函数
cv::xfeatures2d::SURF::create( double hessianThreshold = 100,
int nOctaves = 4, int nOctaveLayers = 3, bool extended = false,
bool upright = false )
hessianThreshold,默认值在300~500之间;
Octaves,4表示在四个尺度空间;
OctaveLayers,表示每个尺度空间的层数;
extended,扩展描述符标志(true使用扩展的128个元素的描述符,false使用64个元素的描述符);
upright,0表示计算选择不变性(如旋转不变性),1表示不计算,速度更快;
绘制关键点:drawKeypoints()函数
此函数用于绘制关键点。
void drawKeypoints( const Mat& image, const vector<KeyPoint>& keypoints,
Mat& outImage, const Scalar& color = Scalar::all(-1),
int flags = DrawMatchesFlags::DEFAULT )
const Mat&类型的src,输入图像;
const vector&类型的keypoints,根据源图像得到的特征点。它是一个输出参数;
Mat&类型的outImage,输出图像,其内容取决于第五个参数标识符flags;
const Scalar&类型的color,关键点的颜色,有默认值;
int类型的flags,绘制关键点的特征标识符费,可以有下面这个结构体中选取值:
struct DrawMatchesFlags
{
enum
{
DEFAULT = 0,//创建输出图像矩阵(使用Mat::create)。使用现存的输出图像
绘制匹配对和特征点。且对每一个关键点,只绘制中间点。
DRAW_OVER_OUTIMG = 1,//不创建输出图像矩阵,而是在输出图像上绘制匹配对
NOT_ORAW_SINGLE_POINTS = 2,//单点特征点不被绘制
DRAW_RICH_KEYPOINTS = 4,//对每一个关键点,绘制带大小和方向的关键点圆圈
};
};
示例:
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>
#include <iostream>
using namespace cv;
using namespace cv::xfeatures2d;
using namespace std;
Mat g_srcImage, g_grayImage, g_keyPointImage;
int main()
{
g_srcImage = cv::imread("curry_dlt.jpg", 0);
if (g_srcImage.empty())
{
printf("read image fail\n");
return -1;
}
imshow("g_srcImage", g_srcImage);
int minHessian = 400;
// SURF特征检测
vector<KeyPoint> keyPoints;
Ptr<SURF> detector = SURF::create(minHessian); //创建一个检测器
detector->detect(g_srcImage, keyPoints, Mat());
// 绘制关键点
g_keyPointImage = g_srcImage.clone();
drawKeypoints(g_srcImage, keyPoints, g_keyPointImage, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
imshow("g_keyPointImage", g_keyPointImage);
waitKey(0);
return 0;
}
运行结果: