SIFT算法分析

引言

尺度不变特征变换(SITF)是传统机器学习算法当中比较难的一个算法,步骤也相对其它传统机器学习算法要更多一些。

使用场景

在这里插入图片描述
以上是一个图像拼接的过程,两张图像拼接成一张图,有时候由于镜头限制,不能一次性拍下全景(当然现在的技术已经有了全景拍摄技术,但这时相对于传统机器学习的算法,当时摄像技术还没有这么成熟),于是就有了图像的拼接。在这样的多幅图像的合成当中,我们首先会在待合成的图像中提取一些关键点的特征,然后将关键点的特征进行一些匹配,然后才能拼接。那么提取关键点的特征,用到的就是本文所要探讨的SIFT技术

在这里插入图片描述

这里注意拼接的过程不是简单的对接过程,而是一个叠放的过程,这也是我们需要进行特征点提取的原因。那么问题来了,我们应该怎么去叠放,叠放的位置又是怎样的呢,这时我们就需要进行特征点提取过后的一个特征点的匹配,当我们发现两张图中的一些特征点是属于同一个物体时,我们就可以将它们进行重叠。
在这里插入图片描述

SIFT(尺度不变特征变换)
Sift(尺度不变特征变换),全称是Scale Invariant Feature Transform
Sift提取图像的局部特征,在尺度空间寻找极值点,并提取出其位置、尺度、方向信息。 Sfit的应用范围包括物体辨别、机器人地图感知与导航、影像拼接、3D模型建立、手势识别、影像追踪等。
Sift特征的特点:

  1. 对视角变化、噪声等也存在一定程度的稳定性;
  2. 独特性,信息量丰富,适用于在海量特征数据中进行快速,准确的匹配;
  3. 多量性,即使少数几个物体也可以产生大量的Sfit特征向量;

Sfit算法的实质是在不同的尺度空间上查找关键点(特征点),计算关键点的大小、方向、尺度信息,利 用这些信息组成关键点对特征点进行描述的问题。Sift所查找的关键点都是一些十分突出,不会因光照, 仿射变换和噪声等因素而变换的“稳定”特征点,如角点、边缘点、暗区的亮点以及亮区的暗点等。 匹配的过程就是对比这些特征点的过程:
在这里插入图片描述

Python中的SIFT函数

SIFT函数注册了专利,在商业用途上是收费的。将在opencv > 3.4.3中,不再提供。
解决办法:
安装opencv-python 3.4.2.16
以及opencv-contrib-python 3.4.2.16
使用conda和pip安装
pip install opencv-python == 3.4.2.16
pip install opencv-contrib-python ==3.4.2.16

SIFT特征提取和匹配具体步骤

  1. 生成高斯差分金字塔(DOG金字塔),尺度空间构建
  2. 空间极值点检测(关键点的初步查探)
  3. 稳定关键点的精确定位
  4. 稳定关键点方向信息分配
  5. 关键点描述
  6. 特征点匹配

我们需要找的就是位置,尺度,方向三个信息

1. SIFT–尺度空间
首先我们来了解一下尺度空间的概念

尺度空间,在摄像头中,计算机无法分辨一个景物的尺度信息。而人眼不同,除了人大脑里已经对物体 有了基本的概念(例如正常人在十几米外看到苹果,和在近距离看到苹果,都能认出是苹果)以外,人 眼在距离物体近时,能够获得物体足够多的特性,在距离物体远时,能够忽略细节,例如,近距离看一 个人脸能看到毛孔,距离远了看不到毛孔等等。

在图片信息当中,分辨率都是固定的,要想得到类似人眼的效果,就要把图片弄成不同的分辨率,制作 成图像金字塔来模拟人眼的功能,从而在其他图片中进行特征识别时,能够像人眼睛一样,即使要识别 的物体尺寸变大或者变小,也能够识别出来。

尺度空间,即,试图在图像领域中模拟人眼观察物体的概念与方法。例如:观察一颗树,关键在于我们 想要观察是树叶子还是整棵树:如果是一整棵树(相当于大尺度情况下观察),那么就应该去除图像的细节 部分。如果是树叶(小尺度情况下观察),那么就该观察局部细节特征。

2. SIFT–图像金字塔

通俗地说,尺度空间,就相当于一个图片需要获得多少分辨率的量级。如果把一个图片从原始分辨率 不停的对其分辨率进行减少,然后将这些图片摞在一起,可以看成一个四棱锥的样式,这个东西就叫 做图像金字塔。

图像金字塔是一种以多分辨率来解释图像的结构,通过对原始图像进行多尺度像素采样的方式,生成N 个不同分辨率的图像。把具有最高级别分辨率的图像放在底部,以金字塔形状排列,往上是一系列像 素(尺寸)逐渐降低的图像,一直到金字塔的顶部只包含一个像素点的图像,这就构成了传统意义上 的图像金字塔。在这里插入图片描述
获得图像金字塔一般包括二个步骤:

  1. 利用滤波器平滑图像 (高斯滤波)
  2. 对平滑图像进行抽样(采样)
    有两种采样方式——上采样(分辨率逐级升高)和下采样(分辨率逐级降低)

3. SIFT–高斯金字塔

主要思想是通过对原始图像进行尺度变换,获得图像多尺度下的尺度空间表示序列,对这些序列进 行尺度空间主轮廓的提取,并以该主轮廓作为一种特征向量,实现边缘、角点检测不同分辨率上的 关键点提取等。
各尺度下图像的模糊度逐渐变大,能够模拟人在距离目标由近到远时目标物体在视网膜上的形成过 程。
尺度空间构建的基础是DOG金字塔,DOG金字塔构建的基础是高斯金字塔。

高斯金字塔是在SIFT中提出来的概念,首先高斯金字塔并不是一个金字塔,而是有很多组(Octave) 金字塔构成,并且每组金字塔都包含若干层(Interval)。

高斯金字塔构建过程:

  1. 先将原图像扩大一倍之后作为高斯金字塔的第1组第1层,将第1组第1层图像经高斯卷积(其实就 是高斯平滑或称高斯滤波)之后作为第1组金字塔的第2层。
  2. 将σ乘以一个比例系数k,得到一个新的平滑因子σ=k*σ,用它来平滑第1组第2层图像,结果图像作 为第3层。
  3. 如此这般重复,最后得到L层图像,在同一组中,每一层图像的尺寸都是一样的,只是平滑系数不一样。它们对应的平滑系数分别为:0,σ,kσ,k^2σ k^3σ…… k^(L-2)σ。
  4. 将第1组倒数第三层图像作比例因子为2的降采样(尺寸减半),得到的图像作为第2组的第1层, 然后对第2组的第1层图像做平滑因子为σ的高斯平滑,得到第2组的第2层,就像步骤2中一样,如 此得到第2组的L层图像,同组内它们的尺寸是一样的,对应的平滑系数分别为:0,σ,kσ, k^2σ k^3σ…… k^(L-2)σ。但是在尺寸方面第2组是第1组图像的一半
    在这里插入图片描述
    反复执行,就可以得到一共O组,每组L层,共计O*L个图像,这些图像一起就构成了高斯金字塔:
  • 在同一组内,不同层图像的尺寸是一样的,后一层图像的 高斯平滑因子σ是前一层图像平滑因子的k倍;
  • 在不同组间,后一组第一个图像是前一组倒数第三个图像 的二分之一采样,图像大小是前一组的一半;
    在这里插入图片描述
    在这里插入图片描述
    SIFT算法在构建尺度空间时候采取高斯核函数进行滤波,使原始图像保存最多的细节特征,经过高斯滤波 后细节特征逐渐减少来模拟大尺度情况下的特征表示。
    其实尺度空间图像生成就是当前图像与不同尺度核参数σ进行卷积运算后产生的图像。
    L(x, y, σ) 定义为,原始图像I(x, y)与一个可变尺度的2维高斯函数G(x, y, σ) 卷积运算。
    在这里插入图片描述

SIFT–构建尺度空间
在高斯金字塔中一共生成O组L层不同尺度的图像,这两个量合起来(O,L)就构成了高斯金字塔的尺 度空间,也就是说以高斯金字塔的组O作为二维坐标系的一个坐标,不同层L作为另一个坐标,则给定 的一组坐标(O,L)就可以唯一确定高斯金字塔中的一幅图像。 尺度空间的形象表述:
在这里插入图片描述

5. SIFT–DOG金字塔
尺度空间构建的基础是DOG金字塔,DOG金字塔构建的基础是高斯金字塔。

差分金字塔,DOG(Difference of Gaussian)金字塔是在高斯金字塔的基础上构建起来的, 其实生成高斯金字塔的目的就是为了构建DOG金字塔。

DOG金字塔的第1组第1层是由高斯金字塔的第1组第2层减第1组第1层得到的。以此类推, 逐组逐层生成每一个差分图像,所有差分图像构成差分金字塔。

概括为DOG金字塔的第o组第l层图像是由高斯金字塔的第o组第l+1层减第o组第l层得到的。

在这里插入图片描述

这里注意,高斯差分金字塔就是高斯金字塔做减法得来的,所以高斯差分金字塔每组的层数一定是比高斯金字塔少一层的。关键的问题在于为什么要做这样的减法呢?

因为后续我们需要寻找关键点(特征点),我们对高斯金字塔做减法,其实在这个过程中很多点就已经减没了,减没的那些点,说明在不同的高斯模糊的情况下,它是没有变化的点,这里大家可以想到,做了高斯滤波,但是却没有变化,那就是非特征点。因为高斯滤波首先是滤波,其次它也是卷积操作。滤波虽然说应用场景下是做平滑的,但是它的本质是提取特征。卷积也是一样,是提取局部特征的。也就是说做了滤波后是得到的边缘信息。所以做差值的目的就在于寻找做差值后得0的点,即非特征点。然后得到我们需要的稳定特征。
在这里插入图描述
这里可以看到在不同的高斯模糊情况下,图像都是由边缘特征信息的。

6. SIFT–尺度空间极值检测

特征点是由DOG空间的局部极值点组成的。为了寻找DoG的极值点,每一个像素点要和它所有的相邻 点比较,看其是否比它的图像域和尺度域的相邻点大或者小。 如下图,中间的检测点和它同尺度的8个相邻点和上下相邻尺度对应的9×2个点共26个点比较,以确保 在尺度空间和二维图像空间都检测到极值点。
在这里插入图片描述
注意,局部极值点都是在同一个组当中进行的,所以肯定有这样的问题,某一组当中的第一个图和最后一个图层没有前一张图和下一张图,那该怎么计算? 解决办法是,再用高斯模糊,在高斯金字塔多“模糊”出三张来凑数,所以在DOG中多出两张。

这里要注意一个细节,这里是目标反推的过程,我们虽然是从高斯金字塔生成DOG金字塔,但我们需要知道的事高斯金字塔应该生成多少层,即L的确定,这是跟我的目标有关的,假如目标想要我有3层的关键点,那么我们就需要6层的高斯金字塔,这里6是怎么来的,是因为我们在进行极值检测的时候,3层DOG金字塔就需要5层的金字塔(这其中包括了最前面的一层和最后面的一层,是高斯金字塔多模拟出来的),那么5层的GOG金字塔又是由高斯金字塔做差值得来的,所以这里就需要6层的高斯金字塔,所以这里是反推的过程。是首先确定我们需要需要检测多少个尺度的极值点,然后再确定高斯金字塔的层数所以L是通过S+3来确定的

7. SIFT—高斯金字塔的k值
在这里插入图片描述
s:每组图像中检测s个尺度的极值点。(实际计算时,s通常在3到5之间)
Sift算法中生成高斯金字塔的规则(M,N为原始图像的行数和列数):
在这里插入图片描述
注:s的意思是将来我们在差分高斯金字塔中求极值点的时候,我们要求s层点。

8. SIFT–稳定关键点的精确定位
DOG值对噪声和边缘比较敏感,所以在第2步的尺度空间中检测到的局部极值点还要经过进一步的筛选,去除不稳定和错误检测出的极值点。

利用阈值的方法来限制,在opencv中为contrastThreshold。

9. SIFT–稳定关键点方向信息分配
方法:获取关键点所在尺度空间的邻域,然后计算该区域的梯度和方向,根据计算得到的结果创建方向直方图。可以做如下设定:直方图的峰值为主方向的参数,其他高于主方向百分之80的方向被判定为辅助方向。
在这里插入图片描述

对于任一关键点,其梯度幅值表述为:
在这里插入图片描述
梯度方向为:
在这里插入图片描述

10. SIFT–关键点描述
对于每一个关键点,都拥有位置、尺度以及方向三个信息。为每个关键点建立一个描述符,用一组向量将这个关键点描述出来,使其不随各种变化而改变,比如光照变化、视角变化等等描述子不但包含关键点,也包括关键点周围对其有贡献的邻域点。

描述的思路是:对关键点周围像素区域分块,计算块内梯度直方图,生成具有独特性的向量,这个向量是该区域图像信息的一种抽象表述。

如下图,对于22块,每块最终取8个方向,即可以生成228维度的向量,以这22*8维向量作为中心关键点的数学描述。
在这里插入图片描述
实验结果表明:对于每个关键点采用4×4×8=128维向量表征,综合效果最优(不变性与独特性)。
在这里插入图片描述

11. SIFT–特征点匹配
特征点的匹配是通过计算两组特征点的128维的关键点的欧式距离实现的。
欧式距离越小,则相似度越高,当欧式距离小于设定的阈值时,可以判定为匹配成功。

具体步骤:
1、分别对模板图(参考图,reference image)和实时图(观测图,observation image)建立关键点描述子集合。目标的识别是通过两点集内关键点描述子的比对来完成。具有128维的关键点描述子的相似性度量采用欧式距离。
2、匹配可采取穷举法完成。

代码实现
关键点检测

import cv2
import numpy as np

img = cv2.imread("lenna.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

sift = cv2.xfeatures2d.SIFT_create()
keypoints, descriptor = sift.detectAndCompute(gray, None)

# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS对图像的每个关键点都绘制了圆圈和方向。
img = cv2.drawKeypoints(image=img, outImage=img, keypoints=keypoints,
                        flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
                        color=(51, 163, 236))
                        
#img=cv2.drawKeypoints(gray,keypoints,img)

cv2.imshow('sift_keypoints', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

特征匹配:

import cv2
import numpy as np
 
def drawMatchesKnn_cv2(img1_gray,kp1,img2_gray,kp2,goodMatch):
    h1, w1 = img1_gray.shape[:2]
    h2, w2 = img2_gray.shape[:2]
 
    vis = np.zeros((max(h1, h2), w1 + w2, 3), np.uint8)
    vis[:h1, :w1] = img1_gray
    vis[:h2, w1:w1 + w2] = img2_gray
 
    p1 = [kpp.queryIdx for kpp in goodMatch]
    p2 = [kpp.trainIdx for kpp in goodMatch]
 
    post1 = np.int32([kp1[pp].pt for pp in p1])
    post2 = np.int32([kp2[pp].pt for pp in p2]) + (w1, 0)
 
    for (x1, y1), (x2, y2) in zip(post1, post2):
        cv2.line(vis, (x1, y1), (x2, y2), (0,0,255))
 
    cv2.namedWindow("match",cv2.WINDOW_NORMAL)
    cv2.imshow("match", vis)
 
img1_gray = cv2.imread("iphone1.png")
img2_gray = cv2.imread("iphone2.png")
 
#sift = cv2.SIFT()
sift = cv2.xfeatures2d.SIFT_create()
#sift = cv2.SURF()
 
kp1, des1 = sift.detectAndCompute(img1_gray, None)
kp2, des2 = sift.detectAndCompute(img2_gray, None)
 
# BFmatcher with default parms
bf = cv2.BFMatcher(cv2.NORM_L2)
matches = bf.knnMatch(des1, des2, k = 2)
 
goodMatch = []
for m,n in matches:
    if m.distance < 0.50*n.distance:
        goodMatch.append(m)
 
drawMatchesKnn_cv2(img1_gray,kp1,img2_gray,kp2,goodMatch[:20])
 
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

答疑
在SIFT算法中,关键点的方向是什么意思?

在SIFT(尺度不变特征变换)算法中,关键点的方向指的是在关键点周围的局部图像区域中,特征的主要方向或主导方向。它用于描述关键点周围的特征结构,并为后续的特征匹配和描述子计算提供更多的信息。

关键点的方向可以用一个角度来表示,通常以弧度或度数形式给出。它反映了局部图像区域中的纹理、梯度或特征分布的主要方向。在SIFT算法中,通过计算关键点周围的梯度直方图来确定关键点的主导方向。具体来说,它会在关键点周围的邻域内计算图像的梯度方向和幅值,并将其分配到相应的梯度方向的直方图中。最终,选择具有最大梯度方向的直方图峰值作为关键点的主导方向。

确定关键点的方向有助于使特征描述子具有旋转不变性,即使在图像发生旋转时,关键点仍能准确匹配。它还可以用于后续的特征匹配和对象识别任务,通过比较关键点的方向和描述子之间的相似性来进行匹配和识别。

尺寸和尺度有什么区别?

尺寸(Size)和尺度(Scale)是两个相关但有着不同含义的概念。
尺寸(Size)通常指代物体、图像或物理对象的具体尺寸、大小或尺度。它可以是指长度、宽度、高度或面积等物理度量。尺寸是一个具体的、可测量的数值,通常以标准单位(如米、厘米、像素等)表示。
尺度(Scale)在某些上下文中指的是相对于某个参考尺寸或比例的缩放因子。尺度可以表示物体、图像或数据在不同层次或级别上的大小变化。尺度可以是线性的,也可以是非线性的。在图像处理和计算机视觉中,尺度通常用于表示物体在不同尺寸下的表现,用于寻找、检测或描述不同尺度下的特征。在尺度空间(Scale Space)理论中,图像在不同尺度上通过应用高斯模糊或拉普拉斯算子等尺度变换来构建尺度金字塔。
尺寸和尺度的关系是,尺度是在尺寸的基础上进行的缩放、调整或变换。尺度可以是相对的,它通常表示物体、图像或数据在不同尺寸上的表现。在某些情况下,尺寸和尺度可能具有相似的含义,但在一般情况下,尺寸更侧重于具体的物理度量,而尺度则更侧重于尺寸的变化和变换。

  • 19
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值