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

article/2025/10/25 18:12:59

文章目录

  • 前言
  • 一、建立高斯差分金字塔
    • 1、建立高斯金字塔
    • 2、建立高斯差分金字塔
    • 3、建塔过程中参数的设定及相关细节问题
  • 二、关键点(key points)位置确定
    • 1、阈值化
    • 2、在高斯差分金字塔中找极值点
    • 3、调整极值点位置
    • 4、舍去低对比度的点
    • 5、边缘效应的去除(难点)
  • 三、为关键点赋予方向
    • 1、亚像素点尺度去对应离散点尺度
    • 2、统计
    • 3、找到主方向
  • 四、构建关键点的描述符
    • 1、旋转至主方向所在方向
    • 2、确定关键点附近区域的大小。
    • 3、在确定的区域上做128维描述符统计
  • 总结


前言

SIFT(Scale Invariant Feature Transform)即尺度不变特征变换算法,该特征向量集具有对图像缩放,平移,旋转不变的特征。在对图片进行特征提取及匹配时,对于光照、仿射和投影变换也有一定的不变性,是一个鲁棒性较强的特征提取与匹配算法。

以下是SIFT特征提取与匹配算法的处理流程。

一、建立高斯差分金字塔

1、建立高斯金字塔

我们知道对于高斯核来说,可以用不同的方差σ计算得到不同的高斯核。通过不同尺度的高斯核对原始图像进行卷积(此处方差σ我们称为尺度),卷积过后得到最下方的Octave1图组。而高斯金字塔上方的Octave2图组是由Ovtave1图组进行隔点取点对Octave1图组进行下采样后,再用不同尺度的高斯核进行卷积得到的。也就是:

  1. 对Octave1图组中的图片进行隔点取点下采样
  2. 对下采样后的图组进行不同尺度的高斯核卷积

通过以上两个步骤,得到Octave2图组。那依次类推,Octave3是由Octave2下采样后再卷积得到的…这样,我们得到了高斯金字塔,如下图所示。
在这里插入图片描述

2、建立高斯差分金字塔

我们现在已经得到了图像的高斯金字塔。还不能结束,我们最终的目的是得到高斯差分金字塔。
由于相同图组中的图像大小是一样的,我们将相邻两层的图像像素点相减(此处的相减就是传统意义上的减号),得到差分层。这样我们对不同Octave层都进行此操作,得到高斯差分金字塔,如下图所示。

图2 高斯差分金字塔

3、建塔过程中参数的设定及相关细节问题

此处的参数主要是指两个:

  • O:高斯金字塔中,要有多少个Octave图组
  • S:高斯金字塔中,每个Octave组要有多少层
    在这里插入图片描述

如上图第一个公式,我们要选择多少组其实可以自己设定。但原SIFT论文中给出了建议值。

  • 对于O的选择:M、N指原图像的长和宽,求最小值后开log再减3
  • 对于S的选择:n指我们希望提取多少个图片中的特征。一般2个的话n也就是取2,加上3后S取5

现在萌生了第一个问题,3是怎么来的呢?为什么两个公式中都有3?
答:对于这个问题,我们从结果来分析原因。我们可以看到上图2中的高斯差分金字塔,对于原高斯金字塔中的5张图,进行像素点相减操作后只能得到4张图。对于4张图片我们要找特征点,我们是在尺度空间(在前文中提到方差也就是尺度)中寻找极值点,那除了x、y两个平面方向,还有一个尺度方向,我们可以理解为z轴。那对于最上面的差分层来说,由于它上面已经没有图片了,我们无法在z方向对它进行求导,也就是说我们无法在最上层的差分层找极值点了。同理,最下层的差分层也无法找极值点。
那最上层和最下层都无法找极值点,减去2。此时要注意,我们从高斯金字塔到高斯差分金字塔的变换过程中也损失了1层。再加上损失的这层,2+1,也就是3的由来了。
在这里插入图片描述
第二个疑问,SIFT为什么要建立高斯金字塔这样的一种结构?
答:由于高斯金字塔是逐步下采样得到的一个金字塔状。我们希望算法在对图像进行处理的时候,对于不同拍摄距离得到的图片具有远近特征的不变性。无论摄像机拿的远近,对于同一个物体都可以识别。那高斯金字塔这种下大上小的结构也就模拟了这种构想。同样,用高斯核去卷积实际上是模拟了近处清晰、远处模糊。并且数学上有相关证明:高斯核是唯一一个可以模拟近处清晰、远处模糊的线性核。这也就是为什么我们只能用高斯核的原因。

第三个疑问,建塔过程中的σ如何配置的呢?
答:如下图所示,我们令k=2开n次方。对于Octave1中的第一层,我们直接用σ,第二层就乘上一个σ,即kσ,以此类推。对于Octave2中的第一层,我们取Octave1中的倒数第三层,因为倒数第三层的σ为k^nσ,也就是为了凑2σ,达到一个隔点取点的降采样效果。

第四个疑问,σ0又是如何设置的呢?
由于我们相继本身拍出的相片也不是完全清晰的,也具有一个模糊尺度。在论文中我们认为模糊尺度为0.5,我们希望第一次高斯核卷积后尺度可以达到1.6。那我们用1.52的方差σ0去卷积,就可以得到1.6的尺度。实际上这个过程是利用了高斯核的类勾股数性质,如图右下方公式。
注:用0.5尺度的高斯核去卷积,将得到的结果再用1.52尺度的高斯核去卷积。以上操作跟直接用1.6尺度的高斯核去卷积得到的图片,效果是一样的。
在这里插入图片描述

二、关键点(key points)位置确定

1、阈值化

abs(val) > 0.5*T/n							T=0.04

以上公式,通过阈值化去掉噪声点。

2、在高斯差分金字塔中找极值点

由于我们是在尺度空间中进行极值点的查找的,除了平面x、y轴外还有个尺度的σ轴,所以我们要在26个点(三层)中找到极大值点或极小值点,如下图所示。
在这里插入图片描述
我们通过这种方式,实际上是在离散空间中找到极值点的。实际上,真实极值点存在的位置可能并不是在这些个离散点上的,而是在离散空间中我们找到的极值点附近的点。所以我们通过一些方式找到一个精确的亚像素位置的真正极值点。
那么,用什么方式来进行这个真实极值点寻找呢?泰勒展开。

3、调整极值点位置

在检测到的极值点X0附近做三元二阶泰勒展开,也就是做一个X0处函数的近似,如下图。
在这里插入图片描述
得到f(X)后,我们对f(X)求导,如下:
在这里插入图片描述

此处,我们得到的X一帽,相当于是我们得到的X0相对于真实极值点的位移量。我们将这个值反代入f(X)中,就得到了真实极值点的值,如下。
在这里插入图片描述
当然,在算法实现时,我们求得真实极值点是一个迭代的过程。有三种情况:

  • 设置的迭代条件:X一帽的三个分量x、y、σ均小于0.5时,方可成立。此时位移量已经足够小了,我们就认为已经收敛了。
  • 出现函数不收敛的情况,那我们将这么点直接舍去。
  • 函数已经收敛,但解超出了一定范围,舍去。

4、舍去低对比度的点

|f(X)| < T/n,则舍去X

通过以上公式,舍去对比度较低的点,很可能是个噪声点。

5、边缘效应的去除(难点)

首先,我们引入一个海参矩阵,如下:
在这里插入图片描述
矩阵中的值,实际上就是上文求真实极值点过程中,框选的四个值。
在这里插入图片描述
海参矩阵可以描述函数的局部的曲率。我们希望某个点在x、y两个方向的曲率差不多,否则的话它很可能是一个边缘点。根据数学上的概念,海参矩阵的特征值和曲率是呈正比的。
此处我们不去算它的特征值,太麻烦了。通过引入迹和行列式来代替特征值α和β的关系,如下:
在这里插入图片描述

  1. 若Det(H)<0,说明两个特征值已经异号了,也就是曲率肯定是不接近的,存在边缘效应,直接舍去X点。

  2. 若Det(H)>0且α>β,说明γ>1,如下:
    在这里插入图片描述

由于(γ+1)^2/γ化简后是一个对勾函数,γ>1,也就变成了一个单增函数。那么在γ=1时就是他的最小值。由于γ=α/β,γ的值越小则曲率越低,我们为γ设置一个阈值,建议取10。也就是:
在这里插入图片描述

三、为关键点赋予方向

此时我们已经确定了关键点,下面要做的就是为关键点赋予方向。假设我们找到的关键点如下图,红点是关键点。
在这里插入图片描述

1、亚像素点尺度去对应离散点尺度

首先,我们在高斯金字塔上找到和关键点的σ值最接近的某个高斯图层所对应的尺度σx。(也就是从亚像素点尺度去对应离散点的尺度)

2、统计

统计 以该特征点为圆心,以1.5倍的σx为半径的圆内的所有梯度方向及其梯度幅值,并做1.5σ的高斯滤波。(此处做高斯滤波的意义就是为了加权,使得离中心越近的点权值越高)
在这里插入图片描述

3、找到主方向

通过统计结果找到该特征点的主方向,也可能存在辅方向(>80%则有)。对于有两个方向的特征点,实际上我们是以两个特征点去处理的。
在这里插入图片描述

四、构建关键点的描述符

通过上文操作,我们已经确定了关键点的xy位置信息、尺度σ以及方向。为了方便后续关键点匹配,我们最后一步要做的就是构建关键点的描述符。在SIFT算法中,描述符其实是一个128维的向量。在特征点匹配过程中,通过k近邻等方式对特征点进行匹配。

1、旋转至主方向所在方向

将特征点周围的区域旋转至主方向所对应的方向。这也是SIFT算法具有旋转不变性的原因所在。
在这里插入图片描述

2、确定关键点附近区域的大小。

如下图所示,论文中的区域大小是这样设置的。m取3,mσ是指每个小区域的边长大小。d是指所确定的区域中在x、y方向上有多少个小区域,论文中取4。
在这里插入图片描述

3、在确定的区域上做128维描述符统计

在4×4个子区域中,包含了很多梯度方向。经过高斯加权后,在每个子区域中统计8个方向的梯度长度。128维向量是怎么来的呢?16*8。16是指16个子区域,8是指8个方向。那么我们按照顺序将128个梯度长度标记即可得到关键点的描述符。
在这里插入图片描述
完成关键点进行描述后,我们就可以用K近邻等方式对最接近的两个关键点进行匹配。这样也就完成了特征点的匹配工作啦!

总结

本文具体介绍了SIFT算法的原理及流程。之前用SIFT、SURF、ORB等算法做过相关项目,但仅仅是跑了代码,算法原理也没有很理解。这次终于把SIFT部分梳理通透啦!


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

相关文章

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

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

【Python】:SIFT算法的实现

✨博客主页&#xff1a;米开朗琪罗~&#x1f388; ✨博主爱好&#xff1a;羽毛球&#x1f3f8; ✨年轻人要&#xff1a;Living for the moment&#xff08;活在当下&#xff09;&#xff01;&#x1f4aa; &#x1f3c6;推荐专栏&#xff1a;【图像处理】【千锤百炼Python】【深…

SIFT算法原理

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

计算机视觉——SIFT算法

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

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

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

SIFT算法

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

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

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

SIFT算法详解

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

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

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

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

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

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

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

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

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

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

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

iOS 下拉刷新

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

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

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

小程序下拉刷新的实现

小程序下拉刷新 1.使用onPullDownRefresh()这个方法来实现下拉刷新 例子如下&#xff1a; // 下拉刷新onPullDownRefresh: function () {wx.showNavigationBarLoading() //在标题栏中显示加载图标setTimeout(() > {wx.hideNavigationBarLoading(); //完成停止加载wx.stopP…

Android 下拉刷新实践

1. 手动实现一个下拉刷新功能。 2. 效果图&#xff1a; 3. view结构 4.实现思路 <com.luocc.tim.recycler.RefreshLayoutandroid:layout_width"match_parent"android:layout_height"wrap_content"android:orientation"vertical"><Tex…

【uniapp】页面下拉刷新

目录 一、全局 二、局部 1、一个页面一个下拉刷新 2、一个页面多个下拉刷新&#xff08;切换时滚动条回到顶部&#xff09; 3、一个页面多个下拉刷新&#xff08;切换时恢复滚动条位置&#xff09; 一、全局 修改pages.json的"enablePullDownRefresh": true, …

uniapp 下拉刷新

uniapp 下拉刷新&#xff08;全局&单页面&#xff09; 全局设置 在pages.json文件的globalStyle对象中开启enablePullDownRefresh属性 单页面 在pages.json文件中的pages数组中找到对应的页面&#xff0c;在对应页面的style属性中开启enablePullDownRefresh属性 下拉刷…

Android 下拉刷新框架实现

前段时间项目中用到了下拉刷新功能&#xff0c;之前在网上也找到过类似的demo&#xff0c;但这些demo的质量参差不齐&#xff0c;用户体验也不好&#xff0c;接口设计也不行。最张没办法&#xff0c;终于忍不了了&#xff0c;自己就写了一个下拉刷新的框架&#xff0c;这个框架…