SIFT
- 简介
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的更多相关文章
- sift特征
已经有很多博客已经将sift特征提取算法解释的很清楚了,我只是记录一些我不明白的地方,并且记录几个理解sift特征比较好的博客. 1. http://aishack.in/tutorials/sift ...
- sift特征源码
先贴上我对Opencv3.1中sift源码的注释吧,虽然还有很多没看懂.先从detectAndCompute看起 void SIFT_Impl::detectAndCompute(InputArray ...
- opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较
opencv中的SIFT,SURF,ORB,FAST 特征描叙算子比较 参考: http://wenku.baidu.com/link?url=1aDYAJBCrrK-uk2w3sSNai7h52x_ ...
- 特征描述算子-sift
特征描述算子-sift http://boche.github.io/download/sift/Introduction%20to%20SIFT.pdf
- SIFT特征详解
1.SIFT概述 SIFT的全称是Scale Invariant Feature Transform,尺度不变特征变换,由加拿大教授David G.Lowe提出的.SIFT特征对旋转.尺度缩放.亮度变 ...
- SIFT中的尺度空间和传统图像金字塔
SIFT中的尺度空间和传统图像金字塔 http://www.zhizhihu.com/html/y2010/2146.html 最近自己混淆了好多概念,一边弄明白的同时,也做了一些记录,分享一下.最近 ...
- SIFT特征提取分析
SIFT特征提取分析 sift 关键点,关键点检测 读'D. G. Lowe. Distinctive Image Features from Scale-Invariant Keypoints[J] ...
- SIFT特征提取分析(转载)
转载自: http://blog.csdn.net/abcjennifer/article/details/7639681 SIFT(Scale-invariant feature transform ...
- SIFT定位算法关键步骤的说明
1. SIFT算法中一些符号的说明 $I(x,y)$表示原图像. $G(x,y,\sigma)$表示高斯滤波器,其中$G(x,y,\sigma) = \frac{1}{2\pi\sigma^2}exp ...
- SIFT 特征提取算法总结
原文链接:http://www.cnblogs.com/cfantaisie/archive/2011/06/14/2080917.html 主要步骤 1).尺度空间的生成: 2).检测尺度空间极 ...
随机推荐
- nefu 1116 字符串加密
字符串加密 Problem : 1116 Time Limit : 1000ms Memory Limit : 65536K description 给你一段经过加密的字符串,我们称之为密文,现在请你 ...
- Django:之CMDB资源系统
渐谈CMDB需要内容,ITIL.CMDB介绍.Django自定义用户认证.Restful规范.资产管理功能开发. ITIL介绍 TIL即IT基础架构库(Information Technology I ...
- flash检测网络是否通畅
air: 要在 Adobe ® Flash ® Professional(CS4 或更高版本)中使用 air.net 包: 选择“文件”>“发布设置”命令. 在 Flash 面板中,单击 Act ...
- Git如何删除版本库中的一个提交?
如果不小心增加了一个最新的提交,可以通过以下的操作删除,记住:是删除最新的提交,如果回滚到其他的提交上面,就会导致之后的全部消失. 1.git reset --hard HEAD~1 2.gi ...
- 图解如何 将Excel里的数据导入到sql server数据库中
项目中,经常会碰到如何将Excel里的数据导入到sql server中的问题. 下面,图解如何实现导入Excel中的数据到sql server 2008 R2: Excel截图如下: 查询pub数据库 ...
- Linux下安装php开发框架yaf
yaf框架中文手册:http://yaf.laruence.com/manual/index.html yaf手册:http://www.php.net/manual/en/book.yaf.php ...
- 【语法】修饰符 static extern const
转载自:http://my.oschina.net/u/2560887/blog/552683 一.C语言中的static的作用 在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有 ...
- [转]View属性 之 paddingStart & paddingEnd
[CAUSE] 在写一个自定义View时, 直接复制了Android-Source的XML布局文件, 默认开发SDK版本是4.2.2(Level-API-17), 后因其他原因将SDK版本改为4.1. ...
- MonkeyRunner 实现自动点击截屏后与本地图库进行对比输出
先说下本人是菜鸟,通过网上资料学习,终于调通了MonkeyRunner 实现自动点击截屏后与本地图库进行对比输出,以后做静态UI测试就不需要眼睛盯着看图了,这一切交给MonkeyRunner了. 首先 ...
- 转:全面剖析C#正则表达式
到目前为止,许多的编程语言和工具都包含对正则表达式的支持,当然.NET也不例外,.NET基础类库中包含有一个名称空间和一系列可以充分发挥规则表达式威力的类. 正则表达式的知识可能是不少 ...