SIFT(Scale-Invariant Feature Transform)特征,即尺度不变特征变换,用来侦测与描述图像中的局部性特征。
SIFT算法的应用:
在适当的条件下完成两幅图像中物体的匹配 。
如果两幅图像中的物体一般只是旋转和缩放的关系,加上图像的亮度及对比度的不同,要在这些条件下要实现物体之间的匹配,SIFT算法的先驱及其发明者想到只要找到多于三对物体间的匹配点就可以通过射影几何的理论建立它们的一一对应。
如何找到这样的匹配点呢?SIFT/SURF作者的想法是首先找到图像中的一些“稳定点”,这些点是一些特殊的点,不会因为视角的改变、光照的变化、噪音的干扰而消失,比如角点、边缘点、暗区域的亮点以及亮区域的暗点。这样如果两幅图像中有相同的景物,那么这些稳定点就会在两幅图像的相同景物上同时出现,这样就能实现匹配。因此,SIFT/SURF算法的基础是稳定点。
SIFT算法实现物体识别主要有三大工序:
1、提取关键点;
2、对关键点附加详细的信息(局部特征)也就是所谓的描述器;
3、通过两方特征点(附带上特征向量的关键点)的两两比较找出相互匹配的若干对特征点,也就建立了景物间的对应关系。
提取特征点代码示例:
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/xfeatures2d/nonfree.hpp"
using namespace cv;
using namespace cv::xfeatures2d;
using namespace std;
int main(int argc, char** argv)
{
Mat src = imread("D:/cv400/data/lena.jpg", 0);
if (src.empty())
{
cout << "Load image error..." << endl;
return -1;
}
//namedWindow("input image", WINDOW_AUTOSIZE);
imshow("input image", src);
double t1 = (double)getTickCount();
int numFeatures = 400;
Ptr<SIFT> detector = SIFT::create(numFeatures);
vector<KeyPoint> keypoints;
detector->detect(src, keypoints, Mat());
cout<<"Total KeyPoints : "<< keypoints.size()<<endl;
double t2 = (double)getTickCount();
double t = (t2-t1) / getTickFrequency();
cout << "spend time: " << t << " s"<<endl;
Mat keypoint_img;
drawKeypoints(src, keypoints, keypoint_img, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
//namedWindow("SIFT KeyPoints", WINDOW_AUTOSIZE);
imshow("SIFT KeyPoints", keypoint_img);
waitKey(0);
return 0;
}
运行截图:
此图检测耗时106ms