SURF算法是SIFT算法的加速版, 而SIFT(尺度不变特征转换, ScaleInvariant Feature Transform) 是另一种著名的尺度不变特征检测法。我们知道,SURF相对于SIFT而言,特征点检测的速度有着极大的提升,所以在一些实时视频流物体匹配上有着很强的应用。而SIFT因为其巨大的特征计算量而使得特征点提取的过程异常花费时间,所以在一些注重速度的场合难有应用场景。但是SIFT相对于SURF的优点就是,由于SIFT基于浮点内核计算特征点,因此通常认为, SIFT算法检测的特征在空间和尺度上定位更加精确,所以在要求匹配极度精准且不考虑匹配速度的场合可以考虑使用SIFT算法。
SIFT特征检测的代码仅需要对上面的SURF代码作出一丁点修改即可。
#include "highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/legacy/legacy.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat image01 = imread("C:\\Users\\Administrator\\Desktop\\1_A.jpg", 1);//右图
Mat image02 = imread("C:\\Users\\Administrator\\Desktop\\1_B.jpg", 1);//左图
namedWindow("p1", 0);//显示窗口名字
namedWindow("p2", 0);
imshow("p1", image01);//显示图像
imshow("p2", image02);
//灰度图转换
Mat image1, image2;//声明表示图像的向量
cvtColor(image01, image1, CV_RGB2GRAY);//将彩色图像灰度化,输出为image1
cvtColor(image02, image2, CV_RGB2GRAY);
//提取特征点
SiftFeatureDetector siftDetector(2000);//构造SIFT特征检测器,Hessian矩阵阈值,在这里调整精度,值越大点越少,越精准
vector<KeyPoint> keyPoint1, keyPoint2;//特征点的向量
siftDetector.detect(image1, keyPoint1);//检测SURF特征
siftDetector.detect(image2, keyPoint2);
//特征点描述,为下边的特征点匹配做准备
SiftDescriptorExtractor SiftDescriptor;//构造SIFT描述子提取器
Mat imageDesc1, imageDesc2;
SiftDescriptor.compute(image1, keyPoint1, imageDesc1);//提取SIFT描述子
SiftDescriptor.compute(image2, keyPoint2, imageDesc2);
//获得匹配特征点,并提取最优配对
FlannBasedMatcher matcher;//构造匹配器
vector<DMatch> matchePoints;
matcher.match(imageDesc1, imageDesc2, matchePoints, Mat());//匹配两幅图像的描述子
cout << "total match points: " << matchePoints.size() << endl;//一共的匹配点数
Mat img_match;
drawMatches(//使用函数 drawMatches来绘制检测到的匹配点
image01, keyPoint1, //第一幅图像及其特征点
image02, keyPoint2, //第二幅图像及其特征点
matchePoints, //匹配结果
img_match//生成的图像
);
imshow("match",img_match);
imwrite("C:\\Users\\Administrator\\Desktop\\match.jpg", img_match);
waitKey();
return 0;
}
输入图像:
输出图像: