sift = scale invariant feature transform—— 尺度不变特征变换,具有尺度,旋转,仿射,视角,光照不变性。。
关于sift的特征介绍,已经有很多的blog对其进行简介了,见参考的blog。我也没有将2004年那篇原文精细看完,这里只是提供在opencv中如何实现 sift关键点的检测。
Code:
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\nonfree\nonfree.hpp> // sift特征在这个头文件中
using namespace std;
using namespace cv;
int main()
{
Mat image = imread("F:\\lena.png", 1);
if(!image.data)
{
cout << "Fail to load image" << endl;
return 0;
}
vector<KeyPoint> keypoints; // 存放关键点
SiftFeatureDetector sift(0.03, 10.0); // 其中0.03代表特征的阀值:用于去除低对比度的关键点 10是用于降低直线敏感度的阀值:去除不稳点的边缘响应点
sift.detect(image, keypoints);
drawKeypoints(image, keypoints, image, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
namedWindow("sift");
imshow("sift", image);
waitKey(0);
return 0;
}
Explanation:
<1>sift函数阀值介绍见代码注释
<2>drawKeypoints函数:
(1)设置特征点的颜色时可以赋予一个负值,这将产生有趣的结果,即绘制的圆将拥有不同的随机颜色
(2)绘制标记参数:
struct DrawMatchesFlags{ enum {
DEFAULT = 0, // 输出图像将被创建(Mat::create),
// 只画出特征点,而不画出周围的circle包含特征点的大小和方向.
DRAW_OVER_OUTIMG = 1, // 输出图像将被创建(using Mat::create),匹配点将被画在输出图像的内容上.
NOT_DRAW_SINGLE_POINTS = 2, // 单个的点不画出.
DRAW_RICH_KEYPOINTS = 4 // 对每个特征点周围的circle,包含特征点的大小和方向将被画出.
};
};
Result:
参考blog:
http://www.cnblogs.com/cfantaisie/archive/2011/06/14/2080917.html
http://blog.csdn.net/abcjennifer/article/details/7639681
http://blog.csdn.net/xiaowei_cqu/article/details/8069548
http://www.cnblogs.com/tornadomeet/archive/2012/08/16/2643168.html