sift算法原理,按步骤记录

article/2025/4/20 0:52:00

sitf算法是一种描述图像特征的,重要的,基础的方法。主要由以下几个步骤构成:

0.尺度空间理论

尺度空间理论认为,人眼在认知画面时,在不同的尺度上使用的是不同特征,例如观察树叶时使用的是小尺度特征,观察大树时则是一个整体,因此sitf算法使用高斯模糊来构造大尺度特征。

提取的特征可能是某些角点、某些边缘,相似的图片或能检测出大量相同特征,可以用于物体的识别,图像的匹配等。

1.构造尺度空间——高斯金字塔

sift的第一步便是构建图像在每个尺度上的画面,具体为对图像做不同程度的高斯模糊,然后降采样,构建一组从大到小的高斯金字塔,如图所示:
在这里插入图片描述
具体为:每一组金字塔都对应着相同的缩放比例,以及高斯模糊标准差 σ \sigma σ

步骤如下:

  • 定义高斯金字塔的组数:
    O = [ l o g 2 ( m i n ( W , H ) ) ] − t O=[log_{2}(min(W,H))]-t O=[log2(min(W,H))]t

W , H W,H W,H是图像宽高, t t t是最小尺度的图像尺寸,如设置3x3为最小尺寸, t = 3 t=3 t=3,相同尺寸图像视为一组

  • 计算每一组,组内每一层的标准差(后面统称为“尺度”):
    σ ( o , s ) = σ 0 ∗ 2 o + S s \sigma (o,s)=\sigma _{0}*2^{o+\frac{S}{s}} σ(o,s)=σ02o+sS o 全 是 小 写 o全是小写 o

s是层的序号,S是每组的层数, σ 0 \sigma _{0} σ0是初始尺度,根据lowe的论文, σ 0 = 1.6 \sigma _{0}=1.6 σ0=1.6
当前组的每一层 σ \sigma σ是上一组对应层 σ \sigma σ的两倍

  • 对原图使用第0组高斯模糊,生成第0组图像
  • 对第0组图像的倒数第二层隔点降采样生成第1组的底层图像(也可以使用倒数第三层)

“这样可以保持图像的尺度连续性”??

  • 对第1组的底层图像使用第1组的高斯模糊,生成第1组图像
  • 同样依次生成每一组图像

2.更好的DOG金字塔
sift点是由DOG空间的局部极值点组成的,关键点的初步探查是通过同一组内各DoG相邻两层图像之间比较完成的,DOG空间实际上就是两层高斯模糊相减,这个操作使得sift有尺度不变性质。

继续步骤:

  • 计算-1组图像——将原图放大2倍,同样计算 σ \sigma σ和高斯模糊

lowe认为第0层做了高斯之后损失了细节,需要对图像做2倍扩展,增加信息。
放大方式可以使用任意算法,如bilinear

  • 将相邻两层的高斯金字塔相减,生成DOG金字塔

后面会提到,1层特征点需要3层DOG图像,也就是需要4层高斯图像
n层特征点需要n+2层DOG,n+3层高斯
在这里插入图片描述

3.获取局部极值点

  • 在三层DOG结构中,用3x3x3的窗搜索出中心点大于所有其它点,或小于所有其它点的点作为极值点。
    在这里插入图片描述

通过尺度来提取特征点,可使特征具有缩放的不变性

  • 获取精确极值点
    图像中的点是离散点,而真正的特征点可能不在图像的某个像素位置,lowe通过对DOG图像做曲线拟合,修正极值点 x , y , σ x,y,\sigma x,y,σ的值,找到最佳的极值点。
    这一步的做法是:对极值点处的图像做泰勒展开,然后求导,导数等于0的地方就是真正的极值点
    在这里插入图片描述
    极值点求解公式:

    X ^ = − ∂ 2 D − 1 ∂ x 2 ∂ D ∂ x \widehat{X} = - \frac{\partial^2 D^{-1}}{\partial x^2}\frac{\partial D}{\partial x} X =x22D1xD

    拟合公式为:

    D ( X ^ ) = D + 1 2 ∗ ∂ D T ∂ X ∗ X ^ , X = ( x , y , σ ) T D(\widehat{X}) = D + \frac{1}{2} * \frac{\partial D^{T}}{\partial X}*\widehat{X} , X = (x,y,\sigma)^{T} D(X )=D+21XDTX ,X=(x,y,σ)T

研究表明所有结果小于0.04的点都可忽视(像素范围[0,1])
其中D是该层的DOG图像, X ^ \widehat{X} X 是修正值,是相对于真正极值点的偏移量
Lowe在拟合修正的结果上再做拟合修正,一共做了五次
感觉很难说清楚,详细可见 :关键步骤的说明、极值点的精确定位

4.去除边缘效应

DOG算子在图像边缘处有比较强的边缘效应
在这里插入图片描述

  • 去除边缘效应产生的多余点
    T r ( H ) 2 D e t ( H ) < ( r + 1 ) 2 r \frac{Tr(H)^{2}}{Det(H)}<\frac{(r+1)^{2}}{r} Det(H)Tr(H)2<r(r+1)2

    T r ( H ) = D x x + D y y Tr(H) = D_{xx}+D_{yy} Tr(H)=Dxx+Dyy

    D e t ( H ) = D x x D y y − D x y 2 Det(H)=D_{xx}D_{yy}-D_{xy}^{2} Det(H)=DxxDyyDxy2

满足该不等式的点保留,不满足的丢弃,建议 r = 10 r = 10 r=10
主要是去除边缘点,保留角点,认为边缘点对噪声有较差的鲁棒性
数学推导:SIFT算法原理(2)-极值点的精确定位
图像的二阶导数计算

5.特征点构造

  • 计算邻域内每个像素的梯度

    我们通过极值点的邻域总方向,来确定极值点的梯度方向,邻域半径为 3 ∗ 1.5 ∗ σ 3*1.5*\sigma 31.5σ

    首先,对邻域中的每个点计算梯度幅值和方向:

    m ( x , y ) = ( L ( x + 1 , y ) − L ( x − 1 , y ) ) 2 + ( L ( x , y + 1 ) − L ( x , y − 1 ) ) 2 m(x,y)=\sqrt {(L(x+1,y)-L(x-1,y))^2 + (L(x,y+1)-L(x,y-1))^2} m(x,y)=(L(x+1,y)L(x1,y))2+(L(x,y+1)L(x,y1))2

    θ ( x , y ) = t a n − 1 ( ( L ( x + 1 , y ) − L ( x − 1 , y ) ) / ( L ( x , y + 1 ) − L ( x , y − 1 ) ) ) \theta (x,y)=tan^{-1} ((L(x+1,y)-L(x-1,y))/(L(x,y+1)-L(x,y-1))) θ(x,y)=tan1((L(x+1,y)L(x1,y))/(L(x,y+1)L(x,y1)))

这些步骤应该在对应高斯层进行

  • 计算梯度直方图
    梯度直方图将360度的角度范围平均分成36个方向,统计极值点邻域内,每个梯度方向的点的个数,直方图最大值的索引方向为主方向,保留峰值大于主方向峰值80%的方向作为该关键点的辅方向。
    在这里插入图片描述

  • 计算(4x4)x8=128维描述子

    (1)根据主方向旋转8x8邻域,坐标变换矩阵为:

    ( x ^ y ^ ) = ( c o s θ − s i n θ s i m θ c o s θ ) ( x y ) \begin{pmatrix} \widehat{x} \\ \widehat{y} \end{pmatrix} = \begin{pmatrix} cos\theta & -sin\theta \\ sim\theta & cos\theta \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} (x y )=(cosθsimθsinθcosθ)(xy)

    由此,我们可以获得旋转后采样点落在子区域的下标:

    ( x n y n ) = 1 3 σ o ( x ′ y ′ ) + d 2 \begin{pmatrix} x^{n}\\ y^{n} \end{pmatrix} = \frac{1}{3\sigma _{o}}\begin{pmatrix} x' \\ y' \end{pmatrix} + \frac{d}{2} (xnyn)=3σo1(xy)+2d

    其中 σ o \sigma_{o} σo为所在层的尺度,d=4是区域数, x n , y n x^n,y^n xn,yn是区域下标。

    注意:由于图像旋转后,像素坐标基本不在整数像素点上,因此必须使用 【双线性插值】 重新获得旋转后区域中的像素。
    在这里插入图片描述

    (2)重新获取邻域,半径为:

    r a d i u s = 3 σ o ∗ 2 ∗ 5 + 1 2 radius=\frac{3\sigma_{o}*\sqrt{2}*5 + 1}{2} radius=23σo2 5+1

  (3)计算像素梯度,乘以高斯权重,统计子区域直方图
  

w = m ( a + x , b + y ) e − x ′ 2 + y ′ 2 2 ∗ ( 0.5 d ) 2 w = m(a+x,b+y)e^{-\frac{x'^2+y'^2}{2*(0.5d)^2}} w=m(a+x,b+y)e2(0.5d)2x2+y2

  其中a,b为极值点在高斯金字塔图像中的位置坐标,也就是图像坐标,x,y则是当前点与极值点的坐标差,m是该点梯度值,w是该像素经过权重处理后的梯度

  邻域被划分为8x8个子区域,每个区域统计出8个方向的梯度直方图,所有梯度直方图结合成为128维特征向量,但并不是计算区域内每个点的梯度就足够了,为了获得更精确的结果,作者还将周围区域的像素点通过插值的方式纳入当前子区域的直方图统计中,这个下面会讲。

高斯权重的是为了防止位置微小的变化给特征向量带来很大的改变,并且给远离特征点的点赋予较小的权重,以防止错误的匹配
下方的蓝色圆就是高斯函数的覆盖范围,在圈外的像素梯度的权重基本为0

为了减少一个梯度幅值从一个格子漂移(shift)到另一个格子引起的描述子突变,需要对梯度值做三线性插值。也就是根据三维坐标计算距离周围格子的距离,按距离的倒数计算权重,将梯度幅值按权重分配到临近的格子里。在这里插入图片描述

  (4)梯度三线性插值

  图像梯度需要经过三线性插值算出,比双线性插值多了一个角度维度。其中的原理很难说清除,这里我找到一张图
在这里插入图片描述
  蓝色框是实际的像素点,我们需要比实际的半径范围还要大的区域来统计。

  上图中红色圆圈标识出了目标子区域,该区域的8方向梯度直方图是由周围的四个蓝色的实际像素区域内的像素通过三线性插值统计得出,不论远近。
图中红点对红圈处某个方向的插值公式为:

w e i g h t = w ∗ ( 1 − d r ) ∗ ( 1 − d c ) ∗ ( 1 − d o ) weight= w*(1-dr)*(1-dc)*(1-do) weight=w(1dr)(1dc)(1do)

  其中dr,dc分别为周围某一点距离绿色区域中心的横向和纵向距离,do则是这个点的实际梯度方向与直方图中最近方向的角度(8方向直方图每个方向相隔45度,这里取最近的那个方向,这里的1指的是实际蓝色框的长度,但是对于角度,这个1指的是啥?是360?)

  最后,还要把这个weight加到最绿框中邻近的那根直方图上。

因此,经过三线性插值后,得到的是它对相邻两个方向的贡献值,直方图是由这所有贡献值相加得到的

全部计算完成之后,我们就得到了4x4x8=128个方向H=(h1,h2,…,h128),最后对128维向量归一化。

H i = h i ∑ j = 1 128 h j 2 H_{i}=\frac{h_{i}}{\sqrt{\sum_{j=1}^{128}h_{j}^{2}}} Hi=j=1128hj2 hi

非线性光照,相机饱和度变化对造成某些方向的梯度值过大,而对方向的影响微弱。因此设置门限值(向量归一化后,一般取0.2)截断较大的梯度值(大于0.2的则就令它等于0.2,小于0.2的则保持不变)。然后再进行一次归一化处理,提高特征的鉴别性。
至此,完成了对一个特征点的描述!

6.特征点匹配

由于穷举法匹配太慢,所以特征点使用的是kd树匹配,概括的说就是根据sift算子在128维空间的点,将空间一分为二、二分为四……,每次分割都将子空间分为两个更小的子空间,然后根据查询点的sift128维坐标,依次判断这个点在哪一个子空间中,是一种巧妙而快速的匹配点查找方法。

实际上kd树也很慢,在其基础上还发展出了很多快速算法。

  • kd树的构造

啊
这里先在二维空间中演示,根据上图, 6个二维数据点{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}构建kd树的具体步骤为:

  1. 确定:split域=x(初始分割方向)。具体是:6个数据点在x,y维度上的数据方差分别为39,28.63,所以在x轴上方差更大,故split域值为x;

  2. 确定:Node-data = (7,2)。具体是:根据x维上的值将数据排序,6个数据的横坐标中值(所谓中值,即中间大小的值)为7(也可以是5),所以Node-data域位数据点(7,2)。这样,该节点的分割超平面就是通过(7,2)并垂直于:split=x轴的直线x=7;

  3. 确定:左子空间和右子空间。具体是:分割平面x=7将整个空间分为两部分:x<=7的部分为左子空间,包含3个节点={(2,3),(5,4),(4,7)};另一部分为右子空间,包含2个节点={(9,6),(8,1)};

  4. 重复分割

形成的kd树如图:
在这里插入图片描述

  • kd树匹配sift
    现在,我们有一个sift特征点,如何在图中找到与它最接近的点呢?

    kd数匹配有正向和反向两个操作,先正向搜索到最末端的节点,这个节点不等于最终结果

  1. 假如我们有一个二维的点(2,4.5),发现它落在节点(7,2)的分割线左侧
  2. 是查询(5,4),发现它位于分割线的上侧
  3. 查询(4,7),发现它位于分割线的左侧,第一步查询完毕
  4. 计算与(4,7)的距离,发现大于和(5,4)的距离,于是以(2,4.5)为圆心,画一个过(5,4)的圆,发现圆接触到了(5,4)的另一个子区域
  5. 检查(2,3),发现(2,3)的距离更近,再画一个过(2,3)的圆,发现没有新的子区域与圆相交,因此确定了查找结果为(2,3)
    在这里插入图片描述

有可能画的圆包含了非常多的子区域,这时候计算就很复杂了
实际上,我们计算的是128为空间,用于分割的是超平面和超圆,算法变得更加难以理解和复杂,在此不多深究,下次研究surf算子的时候再学习一下有什么改进算法。
在这里插入图片描述

详细理论:从K近邻算法、距离度量谈到KD树、SIFT+BBF算法


一篇很详细的参考文档SIFT算法原理详解


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

相关文章

DQN算法流程及原理

相关名词解释&#xff1a; Agent&#xff1a;智能体&#xff1b;s—state&#xff1a;状态&#xff08;放在格子游戏中&#xff0c;就是智能体的位置坐标(x,y))a—action&#xff1a;智能体采取的动作&#xff08;例如上下左右&#xff09;r—reward&#xff1a;奖励&#xff…

D*算法原理与程序详解(Python)

提示&#xff1a;前文写了D搜索算法&#xff0c;是一种贪心算法。 文章目录 一、D*算法是什么&#xff1f;二、原理以及代码步骤1.原理分析2.代码解释 总结 一、D*算法是什么&#xff1f; D*算法也是用于机器人路径规划问题的启发式方法&#xff0c;它是一种局部规划方法&…

unityA星寻路算法基础原理

作者&#xff1a; 风不停息丶 文章目录 &#x1f9d1;‍&#x1f4bb;A星寻路简介&#x1f449;代码基础架构&#x1f44d;代码实现格子类寻路管理类效果 结尾总结 &#x1f9d1;‍&#x1f4bb;A星寻路简介 A*寻路就是用来计算玩家行进路径的&#xff0c;通过它可以计算出避开…

【YOLO系列】YOLO.v1算法原理详解

YOLO(You Only Look Once)系列算法原理 前言 &#xff1a;详细介绍了yolo系列目标检测算法的原理和发展过程。 系列&#xff1a; 【YOLO系列】YOLO.v1算法原理详解 【YOLO系列】YOLO.v2算法原理详解 【YOLO系列】YOLO.v3算法原理详解 【YOLO系列】YOLO.v4 & YOLO.v5算法原…

A*算法原理与实现

前言 A*算法最初发表于1968年&#xff0c;由Stanford研究院的Peter Hart, Nils Nilsson以及Bertram Raphael发表。它可以被认为是Dijkstra算法的扩展。 由于借助启发函数的引导&#xff0c;A*算法通常拥有更好的性能。 一、 A*吸取了Dijkstra 算法中的cost_so_far&#xff0c;为…

激光SLAM之NDT算法(1)算法原理

/在激光SLAM之NDT算法&#xff08;2&#xff09;-建图中我会给出实测可用的建图代码,并予以解释代码结构,这里就先讲讲原理吧!!!/ 无人车激光SLAM系统简单可以分为建图和定位两部分&#xff0c;无人车的定位问题&#xff0c;实际上就是要找出无人车当前在地图的那个位置&#x…

A*算法的原理及应用

A*算法的原理 A* 算法是一种高效的启发式搜索算法&#xff0c;在二维的栅格地图上寻路效果好&#xff0c;它通过估算节点的代价评估函数值并作为节点的综合优先级&#xff0c;当选择下一个需要遍历的节点时&#xff0c;再选取综合优先级最高的节点&#xff0c;逐步地找到最优路…

Bresenham 画圆算法原理

文章目录 前言Bresenham 画圆算法原理两个近似构造判别式圆与网格点的关系关系由来关系含义p i p_i pi​ 递推画圆程序伪码圆与网格点的关系图示前言 首先简要介绍一下生成圆的方法: 直接利用圆的方程生成圆利用圆的对称性生成圆方法一由于会涉及到浮点运算等因素,不采取该方…

Js中读取、移除属性及隐藏组件方法研究

添加、移除组件属性方法: $(".class名").attr("属性名","属性值");//设置指定属性 $(".class名").attr("属性名");//读取指定属性值 or document.getElementById("id值").getAttribute("属性名…

js获取属性值,自定义属性,修改移除属性值

补充&#xff1a;由于不清楚一些属性是内置属性还是自定义属性 所以h5规定 自定义属性使用date-开头作为属性并赋值 案例1: <body><div date-index"1"></div> </body> <script>var div document.querySelector(div);console.log(div…

获取/移除属性值

1.获取属性值&#xff1a; element.属性 获取属性值 element.getAttribute&#xff08;‘属性’&#xff09;&#xff1b; 2.区别&#xff1a; element.属性 获取内置属性值&#xff08;元素本身自带的属性&#xff09; element.getAttribute&#xff08;‘属性’&#xff09;&…

JavaScript移除对象中不必要的属性

Thinking系列&#xff0c;旨在利用10分钟的时间传达一种可落地的编程思想。 业务开发中&#xff0c;我们经常会遇到&#xff1a;基于后端返回接口数据&#xff0c;前端保存到对象 Object 中&#xff0c;前端开发过程中为了一些场景的便利性&#xff0c;需要在该对象中增加相应的…

js移除属性

一、效果 代码 <style>div{width:100px;height: 100px;background-color: red;}.clsP{background-color: #00FF00;}</style><body><input type"button" value"移除属性" id"btn" /><div id"dv" score&q…

合天网安实验室CTF-解密100-Funny Crypto

合天网安实验室CTF-解密100-Funny Crypto 题目描述 tgbnjuy 8ujko9 5rfgy6 相关附件 题目链接 参考解题步骤 字母被围起来的字母图示颜色tgbnjuyh红8ujko9i绿5rfgy6t蓝 提交flag&#xff1a;hit

数字取证之Autopsy ——合天网安实验室学习笔记

实验链接 Autopsy Forensic Browser 是数字取证工具-The Sleuth Kit&#xff08;TSK&#xff09;的图形界面&#xff0c;用于对文件系统和卷进行取证。通过本实验学习文件系统取证的思想与方法&#xff0c;掌握Autopsy的使用。 链接&#xff1a;http://www.hetianlab.com/exp…

【合天网安】CONN.ASP暴库漏洞实验

0x01预备知识 1、概念&#xff1a; 相对路径和绝对路径 绝对路径&#xff1a;例如D&#xff1a;/test/test.mdb 相对路径&#xff1a;例如/test/test.mdb 2、%5C暴库 简单点说&#xff0c;就是在打开页面的时候把网页中的/换成%5C&#xff0c;然后提交就可以得到数据库地址…

【合天网安】FCKeditor 2.4.3文件上传漏洞

【合天网安实验室】FCKeditor 2.4.3文件上传漏洞 编辑器漏洞 常见的文本编辑器有FCKeditor、Ewebeditor、UEditor、KindEditor、XHeditor等&#xff0c;它们包含的功能类似&#xff0c;如图片上传、视频上传、远程下载等。使用这类编辑器减少了程序开发的时间&#xff0c;但也…

摩尔斯电码和栅栏密码 ——合天网安实验室学习笔记

实验链接 通过学习本实验理解摩尔斯电码和栅栏密码的编码解码过程&#xff1b;掌握编写摩尔斯电码的编码解码程序和编写多功能栅栏密码的编码解码程序。 链接&#xff1a;http://www.hetianlab.com/expc.do?ce64d3e661-ebbb-41fd-a220-a17d608f994e 实验简介 实验所属系列…

【合天网安】DoraBox之文件包含及任意文件读取漏洞

【合天网安实验室】DoraBox之文件包含及任意文件读取漏洞 目的&#xff1a; 过DoraBox靶场系列练习&#xff0c;学习任意文件包含、目录限制文件包含及任意文件读取漏洞的利用过程。 实验过程&#xff1a; 1.确保Apache、MySQL服务正常开启 2、查看.txt文本内容 3.使用includ…

合天网安实验室-sql注入实验一

根据指导书我们要先在实验机进入这个网址http://10.1.1.11:81 进入之后会看到三个实例。 实例一 根据指导书的提示来做这一题。后面两个实例也要看这个指导书。 先判断是否存在注入 方法一 在参数后面加上单引号,比如: http://xxx/abc.php?id1’ 如果页面返回错误&#xff…