SIFT算法的个人理解

article/2025/10/26 15:27:22

SIFT算法的个人理解——理论篇

1. 前言

本人目前共使用过两个版本的sift算法:

(1)Matlab中的sift算法,可以从http://www.cs.ubc.ca/~lowe/keypoints/下载Lowe团队写的sift演示代码;

(2)opencv中的sift算法(本人使用的opencv版本是2.4.9),可以从http://opencv.org/下载opencv的各个版本,建议不要用太新的版本,容易出现一些小问题。本篇文章主要总结一下本人最近在做项目的过程当中学习和使用sift算法所遇到的问题,一方面可以和大家在网上交流学习,另一方面可以方便自己以后查阅和复习。

2.  SIFT中常见问题

首先还是介绍一下sift算法的主要步骤:(1)建立尺度空间,主要是指建立,Gaussian金字塔和DoG金子塔;(2)在尺度空间中寻找极值点(keypoints),并对其进行精确定位;(3)求解关键点的梯度幅值和幅角;(4)对关键点进行描述,形成128维的空间向量。

在步骤(1)当中大家需要明白的问题是:(1)什么是尺度?尺度空间中的尺度又是什么?(2)如何建立Gaussian金字塔?(3)如何建立DoG金字塔?(4)为什么要建立尺度空间,不建立尺度空间可以吗?这些问题也是我当初学习的时候遇到的问题,接下来就这些问题谈一谈我自己的认识,希望对大家有所帮助;

问题(1)我举一个简单的例子,相信大家就会明白了,比如你站在远处看一棵树木,你只能看见它的一簇树叶,而当你离树木越来越近的时候,你可以看见单个的树叶,而当你再靠近的时候,你就会看见树叶上的纹络。而在尺度空间当中的尺度在我理解是指图像的大小,对于同一张图像,图像的尺寸越大图像的尺度越大,图像越模糊;尺度越小图像越清晰。而图像中的细节可以在小的尺度上面找到,轮廓可以在大的尺度上面找到。

问题(2)建立高斯金字塔主要包括两个步骤:(a)对图像进行高斯模糊,即通过高斯掩膜对图像进行求卷积(b)对高斯模糊之后的图像进行降采样,即对图像中行和列的像素隔行删除。如示意图1所示

图1 Gaussian金字塔和DoG金字塔的建立示意图

图1左边的是Gaussian金字塔,右边的是DoG金字塔(后面会介绍到),图中octave--组,Layer--层,scale--尺度。如上图Gaussian第一组(first octave)中共有5层,包括0,1,2,3,4 ,第二组(second octave)中共有5层,包括0,1,2,3,4  。第一组的第0层是原始图像放大一倍后得到的,第1层是由第0层经过高斯平滑后得到的,... ,第4层是由第3层经过高斯平滑得到的;而第二组的第0层是由第1组的倒数第三张图像降采样得到的(这个地方是个难点,后面会讲到为什么是这个样子),接下来的步骤和第一组当中是一样的,不再赘述。   

问题(3)向大家介绍一下如何建立DoG金字塔,大家可以从上面的示意图看出,右边的DoG金字塔是通过左边的Gaussian金字塔同一组当中相邻两层相减而得到的,如:DoG金字塔的第1组第0层是通过第Gaussian金字塔的第1组第0层减去第1组的第1层得到的,依次类推。 

问题(4)  尺度空间理论的核心思想是通过对原始图像进行尺度变换,获得图像多尺度下的尺度空间序列,然后对这些序列进行主轮廓的提取,并以该主轮廓作为一种特征向量,实现边缘、角点(这个概念在后面会提到)提取。尺度空间的目的是模拟图像的多尺度特征,再说的简单一点,保证两幅图像在缩放的情况下也可以找到他们共同的特征点,从而能够实现算法的尺度不变性

在步骤(2)当中大家需要明白的问题:(1)尺度空间连续是怎么回事?(2)如何在尺度空间寻找特征点?(3)尺度空间的极值点代表什么?为什么一定要找极值点而不找其他的点?

问题(1)


图2

可以发现以下规律:(a)尺度空间中同一组相邻2层之间的尺度倍数为k(k=2*(1/S),S位尺度空间的组数,Lowe推荐S为3);(b)尺度空间中相邻两组之间的尺度倍数为2(如第1组第0层尺度为sigma,第2组第0层尺度为2*sigma);(3)Gaussian金字塔的的组数为S+3,DoG金字塔的组数为S+2,而最后寻找极值点的尺度空间为S;


上式中:

         sigma0----图像的初始尺度;

        O ----组数的索引值;

        r---每组层数的索引值;

        S---寻找极值点的尺度空间的组数,默认值为3;

 

下面开始进入正题,为什么说寻找极值点的尺度空间是连续的:为了帮助大家理解,帮大家画了一个简单的表格帮助大家理解

表1 尺度空间中的尺度



PS:
在步骤一种提到“而第2组的第0层是由第1组的倒数第三张图像降采样得到的”这个时候可以告诉大家原因了,Gaussian1组的倒数第三张图像的尺度是,假设Gaussian2组的第一张图像是由此图片降采样得到的,可以得到Gaussian2组的第一张图像的尺度是;经过这样的采样可以保证Finalscale space是连续的。读者仔细观察表1就可以发现Final scale space 中的尺度是连续的:


问题(2):如图3所示


图3 尺度空间寻找极值点

如图3所示,尺度空间的特征点是在Final scale space同一组相邻3层寻找,将找到的特征点处的像素与上、中、下3层其他26个点相比较,通过寻找极小值和极大值,即尺度空间中的特征点。

问题(4)

尺度空间的极值点代表这样一类点,如:角点、暗区域的亮点以及亮区域的黑点,这些点是图像中十分突出的点,而且这些点相对比较稳定,在对两幅图像当中具有相同的物体进行SIFT特征点检测的时候,可以分别提取到这些稳定点,然后对这些进行特征点进行匹配。

在步骤3中,大家可能需要明白的问题包括:(1)特征点处的梯度幅值和幅角如何求解?(2)极值点处的主方向和辅方向分别代表什么?

问题(1)


上式中:

x,y---关键点在尺度空间中的位置坐标;

L(x,y)---(x,y)处的像素值;

问题(2)如图4所示


图4 关键点方向直方图

统计关键点直方图的区域半径:r=3*1.5 *sigma,其中sigma为关键点所在层相对于所在组的基准层的高斯尺度图像的尺度,即。而直方图的峰值就代表该关键点处的主方向,而辅方向是代表峰值大于主方向峰值80%以上的方向。在opencv中梯度直方图共有36个bins,上图只是代表示意图。

在步骤4中,大家可能需要明白的问题主要是一个:关键点周围的128维的向量是如何生成的?个人通过总结主要包括以下几步:

(1)  确定计算特征描述符的邻域范围

以特征点为中心周围的d*d个子区域为计算范围,值得注意的是这里的子区域的大小并不是一个像素而边长为的正方形区域,,理论上区域中的像素个数为:opencv当中区域中实际像素个数为:个。为了保证特征点具有旋转不变性,后来还会对图像进行旋转一个角度,为了保证旋转之后的区域能够包括之前的整个正方形,所以 旋转之后区域大小半径为

(2)  图像旋转

如图5所示


图5 图像旋转

       而在实际编程中为了计算方便会将得到的坐标进行单位化,如下面的公式所示:


而上面的公式加上d/2的原因为了将特征点领域范围的坐标原点从中心位置移动到左下角,方便后面编程。

(3)  对关键点周围半径区域内的每个像素点求取其梯度幅值和方向,然后对每一个梯度幅值乘以高斯权重参数,生产3维直方图。求取高斯权重参数的时候较为复杂,如果有兴趣了解的朋友可以和我私下讨论。

(4)  对计算得到的128维向量,进行单位化,就可以得到最终的特征描述符,如下面的公式所示:


3.  其他参考资料

1.http://blog.csdn.net/zhaocj/article/details/42124473(对SIFT的源代码有详细的解释,是目前本人阅读过SIFT最详细的参考资料了)

2.http://www.360doc.com/content/14/1013/15/18306241_416576994.shtml(写的十分详细,对于初学者理解SIFT十分有用)

3. http://www.cs.ubc.ca/~lowe/keypoints/(sift 官网,可以在下面下载SIFT论文以及作者的源代码是,代码是Matlab版本的)。

4. 《图像局部不变性特征与描述》,作者王永明,王贵锦。(此书对于想研究图像中局部特征描述子的朋友可以好好的读一下,书中对于SIFT SURF SUSAN等兴趣点检测的方法都提到了,并且讲解的十分详细)

还有很多关于SIFT资料,我就不一一列举了,大家有兴趣的话可以自己搜索。

4.  总结

自己在这篇博客简单总结了在研究和使用SIFT期间所遇到的问题,只是想和大家分享自己的见解,可能并不是很专业,但是本人会继续努力的,会在后期不断完善和修正这篇博客。

 

PS:这是本人第一次写博客,写的不好还请大家见谅,我很乐意和大家一起讨论问题,大家如果有什么疑问,可以私信我,我的邮箱120349363@qq.com

@2018.2.4  对本博文进行第一次修改,感谢yingshi.ma所提出的建议。

 


http://chatgpt.dhexx.cn/article/DMh9xQmQ.shtml

相关文章

SIFT算法原理解析

首先找到图像中的一些“稳定点”,这些点是一些十分突出的点不会因光照条件的改变而消失,比如角点、边缘点、暗区域的亮点以及亮区域的点,既然两幅图像中有相同的景物,那么使用某种方法分别提取各自的稳定点,这些点之间…

SIFT算法步骤梳理

简介:SIFT算法是检测和描述局部特征的一种方法,具有尺度不变性,对于光线,噪声等的容忍度相当高。即便少数几个物体也可以产生大量SIFT特征。 SIFT算法实质上是在不同尺度空间上查找关键点,并计算出关键点的方向。 算…

SIFT算法原理详解及代码实现(笔记)

一、SIFT算法概述: SIFT(Scale Invariant Feature Transform)全称尺度不变特征变换,SIFT算子是把图像中检测到的特征点用一个128维的特征向量进行描述,因此一幅图像经过SIFT算法后表示为一个128维的特征向量集&#xf…

SIFT算法 特征匹配

目录 一、SIFT算法DOG尺度空间构造(Difference of Gaussian)关键点搜索与定位方向赋值、关键点描述 二、特征匹配 一、SIFT算法 参考链接 【OpenCV】SIFT原理与源码分析 DOG尺度空间构造(Difference of Gaussian) 首先是对原特…

SIFT算法详解——图像特征提取与匹配

文章目录 前言一、建立高斯差分金字塔1、建立高斯金字塔2、建立高斯差分金字塔3、建塔过程中参数的设定及相关细节问题 二、关键点(key points)位置确定1、阈值化2、在高斯差分金字塔中找极值点3、调整极值点位置4、舍去低对比度的点5、边缘效应的去除(难点&#xf…

非常详细的sift算法原理解析

尺度不变特征变换匹配算法详解 Scale Invariant Feature Transform(SIFT) Just For Fun 转自:http://blog.csdn.net/zddblog/article/details/7521424 对于初学者,从David G.Lowe的论文到实现,有许多鸿沟,本文帮你跨越。 1、SIFT综…

【Python】:SIFT算法的实现

✨博客主页:米开朗琪罗~🎈 ✨博主爱好:羽毛球🏸 ✨年轻人要:Living for the moment(活在当下)!💪 🏆推荐专栏:【图像处理】【千锤百炼Python】【深…

SIFT算法原理

SIFT算法 SIFT即尺度不变特征变换,是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。 一、SIFT算法特点: 1、具有较好的稳定性和不变性,能够适应旋转、尺度缩放…

计算机视觉——SIFT算法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、SIFT算法特点二、SIFT算法实质三、SIFT算法实现特征匹配主要有以下流程:1、**特征点位置和尺度的提取**:2、**特征点方向的提取**3、…

SIFT(尺度不变特征变换)算法

目录 SIFT 1、生成高斯差分金字塔,尺度空间构建 2、空间极值点检测 3、稳定关键点的精确定位 4、稳定关键点方向信息分配 5、关键点描述 6、特征点匹配 SIFT SIFT:Scale-Invariant Feature Trainsform即尺度不变特征变换,这是一种图像…

SIFT算法

1. SIFT简介 尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量,此算法由 David Lowe在1999年所发表&#xff…

SIFT算法详解(附有完整代码)

说明:本文旨在给出 SIFT 算法的具体实现,而在 SIFT 详解上只是做出简单介绍,在这里可以给大家推荐一篇好文:https://blog.csdn.net/zddblog/article/details/7521424;结合这篇文章和下文的具体代码实现,我相…

SIFT算法详解

大纲 引言一、高斯金字塔二、高斯差分金字塔三、特征点处理1.阈值化2.非极大值抑制3. 二阶泰勒修正4.低对比度去除5.边缘效应去除 四、特征点描述子1. 确定特征点区域方向2. 特征点区域描述子 总结参考: 引言 SIFT算法是为了解决图片的匹配问题,想要从图…

全网最详细SIFT算法原理实现

文章目录 一、SIFT算法1.1什么是SIFT算法?1.2SIFT算法特点 二、SIFT算法实质2.1SIFT算法实现特征匹配主要有以下三个流程: 三、SIFT算法原理3.1图像金字塔3.2创建图像高斯金字塔3.3高斯金字塔创建总图 四、尺度空间五、高斯差分金字塔5.1极值点(Key poin…

uniapp如何下拉刷新?其实简简单单

uniapp如何上拉刷新?其实简简单单 不论是微信小程序和app上拉刷新功能都是非常常用的,可以说是每个app的标配。 文章目录 uniapp如何上拉刷新?其实简简单单第一步:1.1app全局开启下拉刷新1.2 app中单个页面开启下拉刷新 第二步2.…

uni-app(9)— 下拉刷新以及关闭下拉刷新,上拉加载(页面触底)

此文为uni-app总结笔记(9)— 下拉刷新以及关闭下拉刷新,上拉加载(页面触底) 下拉刷新 开启下拉刷新 在uni-app中有三种方式开启下拉刷新 方法一: 需要在 pages.json 里,找到的当前页面的pag…

上拉刷新和下拉刷新的实现

先来两张效果图 关于下拉刷新,Google提供了一个布局SwipRefreshLayout,它里面可以包涵一个滑动控件,然后你可以设置它的刷新事件就OK了,非常简单用。但是上拉刷新就有点麻烦了。网上很多方法都是给recyclerview添加footer的方法,我…

Flutter 实现下拉刷新和上拉加载

参考 Flutter下拉刷新和上拉加载更多 下拉刷新 上拉加载更多 下拉刷新直接用flutter自带的控件RefreshIndicator组件即可,上拉加载可以通过ListView 中的ScrollController 属性,根据 ListView 的位置来判断是否滑动到了底部来做加载更多的处理 下面用们用…

iOS 下拉刷新

移动应用开发中有这么一种场景,就是在列表中显示的数据刷新,有点击刷新按钮刷新的,也有现在最流行的由Twitter首先推出的下拉刷新功能,在IOS中,使用下拉刷新更新UITableView中的数据也用的非常多,最典型的就…

uniapp几种实现下拉刷新的方式

一.自带刷新 1.在pages.json 上进行定义 2.在页面上监听下拉动作进行需要的操作 ps:一定要手动停止刷新,否则会一直刷新 自带刷新的优点:相对稳定,写法相对简单 自带刷新的缺点:样式上固定的 所以不能满足全部人的需…