1. 简介

SIFT(scale invariant feature transform)——尺度不变特征转换,用来检测和描述局部特征,运用范围包括object recognition(目标检测), robotic mapping and navigation(机器人地图感知与导航), image stitching(图像拼接), 3D modeling(3D建模), gesture recognition(手势识别), video tracking(视频追踪), individual identification of wildlife(野生物个体识别) and match moving(动作匹配)

2.  特点

(1)Sift特征是图像的局部特征,对平移、旋转、尺度缩放、亮度变化、遮挡和噪声等具有良好的不变性,对视觉变化、仿射变换也保持一定程度的稳定性。

(2)独特性好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配。

(3)多量性,即使少数的几个物体也可以产生大量Sift特征向量。

(4)速度相对较快,经优化的Sift匹配算法甚至可以达到实时的要求。

(5)可扩展性强,可以很方便的与其他形式的特征向量进行联合。

3.  算法

           3.1. 构造高斯差分空间图像。

  Sift特征点的检测时在DOG(difference of gausssian)图像上进行的,DOG图像是将相邻尺度空间图像相减得到的。且金字塔的每一层都要构造一个DOG空间图像。默认参数是金字塔4层,即4个octave,每一个octave中有5张不同尺度的图片,不同octave的图片尺寸大小不同,所以每一层中就会得到4幅DOG图像。

高斯金字塔的第1层第1副原图像是将原图像放大2倍且sigma(sigma=1.6)模糊,第2幅图像是k*sigma(k等于根号2)模糊,第3幅是k*k*sigma模糊,后面类推…

高斯金字塔第2层第1幅图是选择金字塔上一层(这里是第1层)中尺度空间参数为k*k*sigma的那幅图(实际上是2倍的尺度空间)进行降采样(尺寸大小为原来的1/4倍)得到,如果k不等于根号2,那么取原图的2*sigma降采样得到。第2层第2幅图是在本层第一幅图尺度模糊系数增加k倍模糊后的图像,后面类似…

  示意图如下所示:

  

3.2、寻找极大极小值点。

  将每个像素点与其所在的那幅图像邻域的8个像素,它所在的向量尺度空间上下2幅图对应位置邻域各9个点,总共26个点进行像素值比较,如果该点是最大或者最小点,则改点就暂时列为特征点。

  其邻图如下:

  

  3.3、精确定位极值点

  子像素级极值点:

  由于上面找到的近似极值点落在像素点的位置上,实际上我们在像素点附近如果用空间曲面去拟合的话,很多情况下极值点都不是恰好在像素点上,而是在附近。所以sift算法提出的作者用泰勒展开找到了亚像素级的特征点。这种点更稳定,更具有代表性。

  消除对比度低的特征点:

  对求出亮度比较低的那些点直接过滤点,程序中的阈值为0.03.

  消除边界上的点:

  处理方法类似harrs角点,把平坦区域和直线边界上的点去掉,即对于是边界上的点但又不是直角上的点,sift算法是不把这些点作为特征点的。

  3.4、选取特征点主方向

  在特征点附近选取一个区域,该区域大小与图图像的尺度有关,尺度越大,区域越大。并对该区域统计36个bin的方向直方图,将直方图中最大bin的那个方向作为该点的主方向,另外大于最大bin80%的方向也可以同时作为主方向。这样的话,由于1个特征点有可能有多个主方向,所以一个特征点有可能有多个128维的描述子。如下图所示:

  

3.5、 构造特征点描述算子。

以特征点为中心,取领域内16*16大小的区域,并把这个区域分成4*4个大小为4*4的小区域,每个小区域内计算加权梯度直方图,该权值分为2部分,其一是该点的梯度大小,其二是改点离特征点的距离(二维高斯的关系),每个小区域直方图分为8个bin,所以一个特征点的维数=4*4*8=128维。示意图如下(该图取的领域为8*8个点,因此描述子向量的维数为32维):

  

4.  在opencv中的使用

// opencv_empty_proj.cpp : 定义控制台应用程序的入口点。
// #include <opencv2/opencv.hpp>
#include <opencv2/features2d/features2d.hpp>
#include<opencv2/nonfree/nonfree.hpp>
#include<opencv2/legacy/legacy.hpp>
#include<vector>
using namespace std;
using namespace cv;
int main()
{
const char* imagename = "SIFT.bmp"; //从文件中读入图像
Mat img = imread(imagename);
Mat img2=imread("SIFT1.bmp"); //如果读入图像失败
if(img.empty())
{
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
if(img2.empty())
{
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
//显示图像
imshow("image before", img);
imshow("image2 before",img2); //sift特征检测
SiftFeatureDetector siftdtc;
vector<KeyPoint>kp1,kp2; siftdtc.detect(img,kp1);
Mat outimg1;
drawKeypoints(img,kp1,outimg1);
imshow("image1 keypoints",outimg1);
KeyPoint kp; vector<KeyPoint>::iterator itvc;
for(itvc=kp1.begin();itvc!=kp1.end();itvc++)
{
cout<<"angle:"<<itvc->angle<<"\t"<<itvc->class_id<<"\t"<<itvc->octave<<"\t"<<itvc->pt<<"\t"<<itvc->response<<endl;
} siftdtc.detect(img2,kp2);
Mat outimg2;
drawKeypoints(img2,kp2,outimg2);
imshow("image2 keypoints",outimg2); SiftDescriptorExtractor extractor;
Mat descriptor1,descriptor2;
BruteForceMatcher<L2<float>> matcher;
vector<DMatch> matches;
Mat img_matches;
extractor.compute(img,kp1,descriptor1);
extractor.compute(img2,kp2,descriptor2); imshow("desc",descriptor1);
cout<<endl<<descriptor1<<endl;
matcher.match(descriptor1,descriptor2,matches); drawMatches(img,kp1,img2,kp2,matches,img_matches);
imshow("matches",img_matches); //此函数等待按键,按键盘任意键就返回
waitKey();
return 0;
}

  

 

SIFT的更多相关文章

  1. sift特征

    已经有很多博客已经将sift特征提取算法解释的很清楚了,我只是记录一些我不明白的地方,并且记录几个理解sift特征比较好的博客. 1. http://aishack.in/tutorials/sift ...

  2. sift特征源码

    先贴上我对Opencv3.1中sift源码的注释吧,虽然还有很多没看懂.先从detectAndCompute看起 void SIFT_Impl::detectAndCompute(InputArray ...

  3. opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较

    opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较 参考: http://wenku.baidu.com/link?url=1aDYAJBCrrK-uk2w3sSNai7h52x_ ...

  4. 特征描述算子-sift

    特征描述算子-sift http://boche.github.io/download/sift/Introduction%20to%20SIFT.pdf

  5. SIFT特征详解

    1.SIFT概述 SIFT的全称是Scale Invariant Feature Transform,尺度不变特征变换,由加拿大教授David G.Lowe提出的.SIFT特征对旋转.尺度缩放.亮度变 ...

  6. SIFT中的尺度空间和传统图像金字塔

    SIFT中的尺度空间和传统图像金字塔 http://www.zhizhihu.com/html/y2010/2146.html 最近自己混淆了好多概念,一边弄明白的同时,也做了一些记录,分享一下.最近 ...

  7. SIFT特征提取分析

    SIFT特征提取分析 sift 关键点,关键点检测 读'D. G. Lowe. Distinctive Image Features from Scale-Invariant Keypoints[J] ...

  8. SIFT特征提取分析(转载)

    转载自: http://blog.csdn.net/abcjennifer/article/details/7639681 SIFT(Scale-invariant feature transform ...

  9. SIFT定位算法关键步骤的说明

    1. SIFT算法中一些符号的说明 $I(x,y)$表示原图像. $G(x,y,\sigma)$表示高斯滤波器,其中$G(x,y,\sigma) = \frac{1}{2\pi\sigma^2}exp ...

  10. SIFT 特征提取算法总结

    原文链接:http://www.cnblogs.com/cfantaisie/archive/2011/06/14/2080917.html   主要步骤 1).尺度空间的生成: 2).检测尺度空间极 ...

随机推荐

  1. differences between null pointer and void pointer.

    These are two different concepts, you cannot compare them. What the difference between the skunk and ...

  2. 获得正在编辑行的数据 esayui datagrid

    function getEditRow(datagridId) {//datagridId为table容器的id var input = $('#' + datagridId).parent().fi ...

  3. apt-key adv

    gpg --recv-keys KEY-ID                gpg --armor --export KEY-ID | sudo apt-key add - http://m.blog ...

  4. Tourists

    Tourists 时间限制: 5 Sec  内存限制: 64 MB 题目描述 In Tree City, there are n tourist attractions uniquely labele ...

  5. Sockets

    Sockets time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...

  6. hdu5269 ZYB loves Xor I

    分治法和字典树都可以,都是递归,但字典树耗内存 从第一bit开始,若相同则xor为0,分到同一部分,不相同则统计,且此时lowbit为这一bit,最后结果要乘以2 /*分治法*/ #include&l ...

  7. XAMPP(v1.83)中的PHP(v5.5.15)访问SQLServer2014

    驱动安装: 1. 下载SQLServer的微软官方PHP驱动,http://msdn.microsoft.com/en-us/sqlserver/ff657782.aspx 2. 安装SQLSRV31 ...

  8. HttpServletResponse对象

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象. request和response对象即然代表请求和响应,那我们 ...

  9. LNMPA by lin

    CentOS系统下执行:wget -c http://soft.vpser.net/lnmp/lnmp1.1-full.tar.gz && tar zxf lnmp1.1-full.t ...

  10. width为auto或者100%的区别

    一.四个理论 1. 某div不显示设置宽度,那么width为auto. 2. 某div的width在默认情况设置的是盒子模型中content的值 3. 某div的width为100%表示的是此div盒 ...