一、角点检测-Harris
1、cv2.cornerHarris
角点检测函数
在 cv2.cornerHarris
函数中,Sobel 算子用于计算图像的梯度,这是 Harris 角点检测的第一步。
cv2.cornerHarris(src, blockSize, ksize, k, dst=None, borderType=None)
下面是各个参数的详细解释:
参数 | 含义 |
---|---|
src | 输入图像。必须是灰度图像(单通道),类型为 numpy.float32 。 |
blockSize | 角点检测中窗口的大小,表示在计算导数矩阵时的邻域大小。 |
ksize | Sobel 算子用于计算图像梯度的核大小,通常为 3。 |
k | Harris 角点检测方程中的自由参数,通常取值范围在 [0.04, 0.06]。 |
dst | 可选的输出图像。通常不需要指定。 |
borderType | 可选的边界模式,用于处理图像边界像素的方式。默认值为 cv2.BORDER_DEFAULT 。 |
# 使用 Harris 角点检测
dst = cv2.cornerHarris(gray, blockSize=2, ksize=3, k=0.04)
返回值:
函数会返回一个浮点型矩阵(单通道),矩阵中每个像素点的值表示 Harris 响应函数的响应值,响应值越大表明角点的可能性越高。
2、Harris 角点检测过程
具体来说,Harris 角点检测的过程包括以下几个步骤:
-
计算图像梯度:
- Sobel 算子在
x
和y
方向上计算图像的梯度(即像素强度的变化率),这是为了找到图像中的边缘信息。 cv2.cornerHarris
函数会对输入的灰度图像应用 Sobel 算子来计算两个方向的梯度: I x I_x Ix 和 I y I_y Iy。ksize
参数决定了 Sobel 算子使用的卷积核大小(如 3x3 或 5x5),它影响计算梯度时的平滑程度。
梯度计算公式:
- 对于水平梯度: Sobel 算子在
x
方向计算: I x = ∂ I / ∂ x I_x = ∂I/∂x Ix=∂I/∂x - 对于垂直梯度: Sobel 算子在
y
方向计算: I y = ∂ I / ∂ y I_y = ∂I/∂y Iy=∂I/∂y
- Sobel 算子在
-
构建结构张量(协方差矩阵):
- 根据计算出的梯度,生成图像的结构张量(也叫协方差矩阵)。这个矩阵在 Harris 算法中用于描述一个像素点的局部邻域特性。
- 结构张量的每个元素依赖于图像的局部梯度平方和:
$
M = \begin{bmatrix} I_x^2 & I_x I_y \ I_x I_y & I_y^2 \end{bmatrix}
$ - 其中, I x I_x Ix 和 I y I_y Iy 是通过 Sobel 算子计算得到的水平和垂直梯度。
-
角点响应计算:
- 使用 Harris 角点检测公式计算角点响应:
$
R = \det(M) - k \cdot (\text{trace}(M))^2
$ - 其中
det(M)
是矩阵的行列式,trace(M)
是矩阵的迹(对角线元素的和),k
是经验参数。
- 使用 Harris 角点检测公式计算角点响应:
-
角点检测:
- 根据计算得到的角点响应值
R
,检测图像中的角点位置。响应值较大的位置被认为是角点。
- 根据计算得到的角点响应值
3、Sobel 在 Harris 角点检测中的作用:
Sobel 算子用于 Harris 算法的第一步,它计算了图像的梯度,这些梯度信息是后续角点检测的基础。具体来说:
- 通过 Sobel 算子得到的梯度图 I x I_x Ix 和 I y I_y Iy,反映了图像中每个像素在水平方向和垂直方向上的强度变化(边缘信息)。
- Sobel 算子帮助 Harris 算法判断图像中哪些区域具有显著的边缘和角点特征。
4、bsize,ksize,矩阵M
blockSize
:
- 在 Harris 角点检测中,涉及到对图像的局部区域进行分析,这个局部区域的大小由
blockSize
决定。- 例如,
blockSize=3
表示在每个像素点的检测中会使用一个 3x3 的窗口来计算该区域的协方差矩阵。blockSize
较大时,角点检测会对图像的较大区域进行平滑,容易忽略小的细节;而较小的blockSize
则能捕捉更多的局部特征。
ksize
:
- 这是 Sobel 算子的参数,Sobel 算子用于计算图像梯度(即像素强度的变化率),并且是角点检测的前置步骤。
ksize
控制 Sobel 算子的窗口大小,例如ksize=3
表示使用 3x3 的 Sobel 核来计算水平和垂直方向的梯度。ksize
较大时,计算得到的梯度会更加平滑,但可能导致细节损失;较小的ksize
能捕捉更多的细节边缘。
blockSize
指定的区域内的所有像素点的 I x I_x Ix 和 I y I_y Iy 值都需要计算出来。这些梯度值用于构建协方差矩阵(结构张量)对于
blockSize
指定的每个窗口,计算该区域内所有像素的梯度值:M = [ ∑ I x 2 ∑ I x I y ∑ I x I y ∑ I y 2 ] M = \begin{bmatrix} \sum I_x^2 & \sum I_x I_y \\ \sum I_x I_y & \sum I_y^2 \end{bmatrix} M=[∑Ix2∑IxIy∑IxIy∑Iy2]
这里的求和是针对整个 b l o c k S i z e × b l o c k S i z e blockSize \times blockSize blockSize×blockSize 的区域进行的。
img = cv2.imread('test_1.jpg')
print ('img.shape:',img.shape)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# gray = np.float32(gray)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
print ('dst.shape:',dst.shape)
# img.shape: (800, 1200, 3)
# dst.shape: (800, 1200)
img[dst>0.01*dst.max()]=[0,0,255]
cv2.imshow('dst',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
二、关于高斯滤波
高斯滤波的实现:
-
高斯核:首先生成一个高斯核(即高斯滤波器),它是一个二维的权重矩阵,形状通常是正方形。高斯核的值由高斯函数决定,通常为:
G ( x , y ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G(x, y) = \frac{1}{2\pi\sigma^2} e^{-\frac{x^2 + y^2}{2\sigma^2}} G(x,y)=2πσ21e−2σ2x2+y2
其中, σ \sigma σ 是标准差,控制高斯分布的宽度。
-
卷积操作:使用这个高斯核与输入图像进行卷积。这一过程将高斯核的每个值与图像对应区域的像素值相乘,然后将结果相加,得到输出图像中对应位置的值。
控制步长与输出尺寸:
- 步长(Stride):步长是卷积操作中高斯核滑动的步幅。如果将步长设置为 1,则高斯核会每个像素都覆盖到,计算出的输出图像会比输入图像小。
- 填充(Padding):为了保持输出图像与输入图像大小相同,通常在输入图像周围增加额外的像素(填充)。这样,在卷积时,高斯核能够在图像的边缘上也能进行计算。
三、关于DOG
DOG(Difference of Gaussian)是一种用于图像处理和特征提取的技术,主要用于检测图像中的边缘和角点。其基本思想是通过两个不同标准差的高斯滤波器之间的差异来实现特征检测。
DOG 的主要用途:
-
边缘检测:
- DOG 可以有效地检测图像中的边缘,尤其是在具有高频细节的图像中。通过比较不同尺度下的高斯模糊效果,DOG 能够突出显示边缘特征。
-
特征提取:
- 在计算机视觉中,DOG 是许多特征提取算法的基础,例如 SIFT(Scale-Invariant Feature Transform)。SIFT 使用 DOG 来检测关键点,从而在不同尺度上提取图像特征。
-
图像平滑与噪声抑制:
- DOG 通过使用高斯滤波器,能够在不同尺度上平滑图像并减少噪声,这对于后续的图像处理步骤非常有用。
DOG 的实现步骤:
-
生成两个高斯模糊图像:
- 对原始图像应用两个不同标准差的高斯滤波器,得到两个模糊图像。
-
计算差异:
- 将两个模糊图像相减,得到 DOG 图像。这个差异图像突出显示了在这两个尺度之间显著变化的区域,通常对应于边缘和角点。
代码示例:
以下是使用 OpenCV 实现 DOG 的一个示例:
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 应用两个高斯模糊
sigma1 = 1.0 # 第一个高斯的标准差
sigma2 = 2.0 # 第二个高斯的标准差
blur1 = cv2.GaussianBlur(img, (0, 0), sigma1)
blur2 = cv2.GaussianBlur(img, (0, 0), sigma2)
# 计算 DOG
dog = blur1 - blur2
# 显示结果
cv2.imshow('DOG Image', dog)
cv2.waitKey(0)
cv2.destroyAllWindows()
总结:
DOG 是一种有效的边缘和特征检测方法,通过对不同尺度下的高斯滤波结果进行差异计算,能够突出显示图像中的重要特征,在计算机视觉和图像处理领域有着广泛的应用。
为何差异计算可以得到特征❤️
通过对不同尺度下的高斯滤波结果进行差异计算,DOG(Difference of Gaussian)能够突出显示图像中的重要特征,这主要是因为以下几个原因:
1. 尺度空间理论:
- ==图像中的特征(如边缘和角点)在不同的尺度( σ \sigma σ)上表现不同。==使用两个不同标准差的高斯滤波器,可以在多个尺度上分析图像,捕捉到不同层次的细节。
- 较小的标准差能够捕捉到图像中的细节特征,而较大的标准差则能够平滑掉这些细节,关注整体结构。
2. 边缘增强:
- 当图像中存在边缘时,边缘两侧的像素值变化较大。应用高斯滤波后,边缘的像素会在较小标准差的高斯模糊中保持较高的响应,而在较大标准差的高斯模糊中会被平滑掉。
- 通过计算这两者的差异,边缘处的响应值会变得显著,从而突出显示边缘特征。
3. 抑制噪声:
- DOG 不仅能够强调特征,还可以抑制图像中的噪声。在较大的尺度下,噪声通常会被平滑掉,因此通过差异计算能够有效减少噪声的影响,保留真正的特征信息。
4. 关键点检测:
- 在使用 DOG 进行关键点检测(如 SIFT)时,DOG 可以帮助识别图像中具有显著变化的区域,这些区域通常是角点或边缘。
- 通过对 DOG 图像进行阈值处理,可以识别出具有局部极值的点,进一步提取出重要的特征点。
总结:
差异计算能够得到特征的核心原因在于不同尺度的高斯模糊分别保留和抑制了图像的不同特征,最终通过计算这两者的差异,能够突出显示图像中最显著的变化(如边缘和角点),从而实现有效的特征检测。这种方法利用了尺度空间的优势,使得图像处理在多种应用中更具灵活性和鲁棒性。
四、SIFT原理
使用 DOG(Difference of Gaussian)进行关键点检测的过程,特别是在 SIFT(Scale-Invariant Feature Transform)算法中,分为几个主要步骤:
1. 构建高斯金字塔与 DOG 金字塔:
- 对图像进行高斯模糊,使用不同标准差 ( σ \sigma σ) 的高斯滤波器来模糊图像。模糊后的图像在不同尺度上形成高斯金字塔。
- ==计算相邻尺度之间的差分,形成 DOG 金字塔。==每一层代表不同尺度下的高斯模糊结果之间的差异。
过程:
- 对原始图像进行高斯滤波,逐渐增加 ( σ \sigma σ) 值,得到多层高斯金字塔。
- 对每一对相邻的高斯模糊图像进行差分,得到多层 DOG 金字塔。
2. 在 DOG 金字塔中检测极值点:
- 对于 DOG 金字塔中的每个像素,比较它与邻近的 26 个像素(即上下两层和当前层的 8 个邻居)。如果该像素是这 26 个像素中的最大值或最小值,则认为它是一个关键点候选。
过程:
- 每个像素与它在相邻尺度(上下层)的 8 个像素和当前尺度(同一层)的 8 个像素进行比较,找出局部极值。
3. 关键点精确定位❤️:
- 对找到的极值点进行精确定位。使用泰勒展开在尺度空间中拟合极值点,并去除对比度过低或位于边缘的点。
过程:
- 对关键点进行二次拟合,以提高检测的精度,去掉那些响应不够显著或在边缘的点。
在 SIFT 算法中,原始的关键点检测是在 DOG(高斯差分)金字塔中通过比较邻域像素值找到的局部极值点。这些极值点是在像素级别上通过简单的比较操作得到的,因此它们的定位是离散的,即受限于图像网格的整数像素位置。
为什么原来的关键点不够精确?
像素级别的限制:
- DOG 算法初步检测到的关键点位置是基于图像的整数像素坐标(即在每个像素之间进行比较)。由于图像的特征可能位于像素之间,而不是恰好在某个像素的整数坐标上,因此初步检测的关键点可能并不完全准确。
- 这种粗粒度的关键点检测只能捕捉到特征的大致位置,但在亚像素级别上可能会有偏差。
响应不显著:
- 一些初步检测到的关键点可能响应值较弱,尤其是当它们处于噪声、低对比度或平滑区域中时。这些点虽然被检测为极值,但对实际图像特征的贡献很小,容易受到噪声干扰。
边缘响应的不稳定性:
- 在 DOG 金字塔中,边缘附近的点也可能表现为局部极值。但这些边缘点通常非常不稳定,容易受到图像细微变化的影响。因此,虽然这些点可能被初步检测为关键点,但它们并不可靠,需要进一步精确定位并排除。
为什么需要精确定位?
获得亚像素级别的精度:
- 真实世界中的图像特征不一定位于整数像素位置上,可能在两个像素之间。因此,检测到的关键点如果仅停留在整数像素位置,会丢失一些重要的细节。通过泰勒展开和二次拟合,SIFT 可以将关键点的定位从整数像素位置扩展到亚像素级别,使特征点的精度更高。
提高关键点的稳定性:
- 在 DOG 金字塔中直接检测到的极值点有时可能受噪声干扰,或者由于对比度不高而不稳定。通过精确定位,可以剔除低对比度或不稳定的关键点,保证留下来的都是对图像整体结构有显著贡献的关键点。
消除边缘响应点:
- 边缘上的极值点虽然可能是初步检测到的关键点,但它们不够稳定。通过对这些点进行进一步分析(如 Hessian 矩阵),可以识别出哪些点是边缘响应,从而将其剔除,确保关键点的稳定性和可靠性。
精确定位的好处:
- 亚像素精度:通过二次拟合和泰勒展开,关键点的坐标可以在亚像素级别上得到精确确定,使得后续的特征匹配更加准确。
- 剔除无效点:通过对比度检测和边缘响应排除,去掉噪声点和边缘不稳定点,确保只保留图像中的重要特征点。
- 提升匹配的鲁棒性:更精确的关键点定位使得这些点在不同尺度、旋转和视角下更加稳定,从而提高了后续特征描述和匹配的鲁棒性。
总结:
初步检测到的关键点虽然是局部极值,但由于整数像素坐标的限制、对比度不强的点以及边缘响应的不稳定性,这些关键点往往不够精确和稳定。通过关键点精确定位步骤,SIFT 可以将关键点的定位提升到亚像素级别,并剔除不稳定的点,确保后续的特征匹配更加准确和鲁棒。
关键点精确定位的具体步骤:
拟合极值点:
- SIFT 使用泰勒展开在尺度空间中对 DOG 金字塔中的局部极值点进行二次拟合,精确确定关键点的位置(包括子像素级别的精度)、尺度和响应值。
- 使用 DOG 函数的二阶泰勒展开近似,将极值点的位置、尺度从整数精度优化到亚像素精度。
泰勒展开公式:
D ( x ) = D + ∂ D ∂ x Δ x + 1 2 Δ x T ∂ 2 D ∂ x 2 Δ x D(x) = D + \frac{\partial D}{\partial x} \Delta x + \frac{1}{2} \Delta x^T \frac{\partial^2 D}{\partial x^2} \Delta x D(x)=D+∂x∂DΔx+21ΔxT∂x2∂2DΔx
其中 D 是 DOG 金字塔中的像素值, Δ x \Delta x Δx 是位置的微小变化。
去除低对比度关键点:
- 对于那些响应较弱的关键点,即 DOG 函数的值较小的关键点,SIFT 将其过滤掉。这是为了确保选出的关键点是图像中的显著特征,而非噪声或模糊区域。
- 如果通过拟合得到的关键点响应值低于某个阈值(通常是 0.03),则该关键点会被丢弃。
去除边缘响应点:
- 边缘响应的点虽然在 DOG 图像中也表现为极值点,但它们不稳定且易受噪声影响。为了避免选择边缘上的关键点,SIFT 使用 Hessian 矩阵的主曲率来判断边缘点,并滤除这些点。
- SIFT 利用 Hessian 矩阵的特征值来衡量局部区域的曲率。如果一个点在某个方向的主曲率远大于另一个方向的主曲率,就认为该点位于边缘,从而将其舍弃。
Hessian 矩阵:
H = [ D x x D x y D x y D y y ] H = \begin{bmatrix} D_{xx} & D_{xy} \\ D_{xy} & D_{yy} \end{bmatrix} H=[DxxDxyDxyDyy]
- 通过计算 Hessian 矩阵的特征值,可以判断某个点是否是边缘点。如果主曲率的比值(即两个特征值的比值)超过某个阈值,通常是 10,那么该点会被认为是边缘点,并被舍弃。
4. 关键点方向分配❤️:
- 为了使得关键点具有旋转不变性,SIFT 为每个关键点分配一个方向。通过计算关键点邻域内的梯度方向直方图,确定主方向(最大值)。
- 为了让 SIFT 特征在不同的旋转角度下保持一致,必须为每个关键点分配一个主方向,这样即使图像发生旋转,特征点仍然可以被匹配。
- 每个特征点可以得到三个信息 ( x , y , σ , θ ) (x,y,σ,θ) (x,y,σ,θ),即位置、尺度和方向。具有多个方向的关键点可以被复制成多份,然后将方向值分别赋给复制后的特征点,一个特征点就产生了多个坐标、尺度相等,但是方向不同的特征点。
过程:
- 在关键点周围计算梯度方向和幅度,使用这些信息构建梯度方向直方图。最大值方向被选为该关键点的主方向。
为什么要得到关键点方向?
为了让 SIFT 特征在不同的旋转角度下保持一致,必须为每个关键点分配一个主方向,这样即使图像发生旋转,特征点仍然可以被匹配。
原因:
- 旋转不变性:图像中的物体可能会因为拍摄角度的变化而旋转。如果不考虑旋转,直接使用图像中的关键点,图像旋转后相同的物体的特征将变得无法匹配。因此,为了让关键点的描述子与旋转无关,必须为每个关键点分配一个主方向。
- 统一特征表示:通过为关键点分配方向,后续生成的特征描述子可以基于这个方向进行计算。这样,当图像旋转时,特征描述子仍然会指向相同的方向,确保特征匹配不受旋转的影响。
2. 如何计算关键点方向?
SIFT 在计算关键点方向时,会选择一个以关键点为中心的局部邻域(通常是一个半径为 3 倍高斯模糊尺度的区域),并计算该区域内每个像素的梯度方向和梯度幅值。然后根据梯度信息构建方向直方图,直方图的峰值代表主方向。
具体步骤:
计算梯度方向和幅值:
- 对关键点邻域内的每个像素,计算其梯度方向和幅值。梯度是通过 Sobel 算子或者差分法得到的。
梯度幅值 m ( x , y ) m(x, y) m(x,y) 和梯度方向 θ ( x , y ) \theta(x, y) θ(x,y) 的公式如下:
m ( x , y ) = ( I ( x + 1 , y ) − I ( x − 1 , y ) ) 2 + ( I ( x , y + 1 ) − I ( x , y − 1 ) ) 2 m(x, y) = \sqrt{(I(x+1, y) - I(x-1, y))^2 + (I(x, y+1) - I(x, y-1))^2} m(x,y)=(I(x+1,y)−I(x−1,y))2+(I(x,y+1)−I(x,y−1))2
θ ( x , y ) = a r c t a n ( I ( x + 1 , y ) − I ( x − 1 , y ) I ( x , y + 1 ) − I ( x , y − 1 ) ) θ(x,y)=arctan(I(x+1,y)−I(x−1,y)I(x,y+1)−I(x,y−1)) θ(x,y)=arctan(I(x+1,y)−I(x−1,y)I(x,y+1)−I(x,y−1))
其中 I ( x , y ) I(x, y) I(x,y)是图像在 ( x , y ) (x, y) (x,y) 位置的像素值。
构建方向直方图:
- 将梯度方向分成 36 个方向(每个方向覆盖 10°),并根据每个像素的梯度幅值为这些方向加权累加,生成一个方向直方图。梯度幅值越大,说明该方向上变化越剧烈,因此该方向在直方图中的权重也越高。
- 在计算梯度时,对距离关键点较远的像素进行高斯加权,距离越远的像素权重越小。这是为了减少远离关键点的像素对方向计算的影响,保证方向主要反映关键点局部的特征。
选择主方向:
- 直方图中的最大值方向被选为该关键点的主方向。有时,若某个方向的次峰值也较大(通常大于主峰值的 80%),则该关键点会分配多个方向,从而在多个方向上增强特征点的描述能力。
3. 为什么要计算邻域?
计算邻域内像素的梯度方向和幅值,是为了确保关键点的方向能够反映局部区域内的图像变化,而不仅仅依赖于单个像素。通过这种方式,计算出的方向可以更稳定和准确,减少噪声或局部异常对方向的影响。
原因:
- 局部稳定性:单个像素的梯度方向可能会受到噪声影响,或者因为它所处的图像区域比较平滑而不够稳定。通过计算关键点邻域内多个像素的梯度方向,SIFT 能够提取出更稳定的方向信息,确保关键点方向是对局部图像变化的真实反映。
- 增强鲁棒性:邻域内的梯度方向能够更全面地反映该区域内的特征信息。通过在邻域内累加多个像素的梯度信息,SIFT 能够捕捉到该区域的主要变化方向,增强特征点的鲁棒性,尤其是在噪声或光照变化情况下。
4. 关键点方向的重要性总结:
- 实现旋转不变性:通过为每个关键点分配主方向,确保图像在旋转时,关键点的描述子不会受影响。即使图像发生旋转,基于关键点主方向构建的描述子仍然可以与其他图像中的对应特征进行正确匹配。
- 稳定关键点描述:计算邻域中的梯度信息并构建方向直方图,可以确保关键点的方向是基于局部区域的整体变化,而不是受单个像素的局部噪声干扰。
总结:
- 得到关键点方向 是为了实现旋转不变性,确保图像旋转时特征点仍能正确匹配。
- 计算邻域的梯度信息 是为了增强方向计算的稳定性和准确性,确保关键点的方向能够反映局部区域的真实变化。
5. 生成关键点描述子:
- 对每个关键点,根据它的主方向,在其周围构建一个 8x8 的窗口,将窗口划分成 4x4 的子区域。在每个子区域内计算梯度方向的直方图,最终生成 32 维的描述子。
过程:
- 每个 4x4 子区域计算 8 个方向的梯度直方图,这样 4 个子区域共生成 32 维的描述子。
旋转之后的主方向为中心取8x8的窗口,求每个像素的梯度幅值和方向,箭头方向代表梯度方向,长度代表梯度幅值,然后利用高斯窗口对其进行加权运算,最后在每个4x4的小块上绘制8个方向的梯度直方图,计算每个梯度方向的累加值,即可形成一个种子点,即每个特征的由4个种子点组成,每个种子点有8个方向的向量信息。
(4,4,8)
特征点方向与邻域内的方向有什么区别?
SIFT 处理关键点方向和邻域内的方向有两个层次:
- 关键点方向(主方向):这是在前面步骤中计算的,表示的是关键点的主要方向,用于实现旋转不变性。通过为每个关键点分配一个方向(或者多个方向),确保即使图像旋转,关键点描述子依然能够被正确匹配。这个方向是通过计算关键点局部区域内像素的梯度信息,生成方向直方图并选择主峰值的方向来得到的。
- 关键点方向的计算是在关键点检测之后,构建描述子之前完成的。它用于归一化关键点局部区域的方向,使得描述子与图像旋转无关。
- 邻域内的方向(用于生成描述子):在生成 SIFT 特征描述子时,对关键点邻域的每个小区域(如 4x4 子区域)都计算梯度方向和梯度幅值,并构建方向直方图。这些直方图表示的是该小区域内的局部方向信息。通过将这些局部方向的信息进行组合,生成一个反映关键点周围结构的 128 维特征向量。
- 这些方向不仅仅反映关键点的主方向,而是描述了关键点周围的多个方向上的变化。这些信息有助于生成更丰富、细致的特征描述子,使其更加鲁棒。
总结:
- SIFT 特征描述子是通过计算关键点邻域内多个小区域的梯度方向和幅值来生成的,每个区域生成一个方向直方图。
- 关键点方向是特征点的主方向,用于对邻域方向进行归一化,确保特征描述子在旋转不变的情况下依然能够有效匹配。
- 邻域方向是描述子生成过程中对关键点周围的局部方向信息进行编码的结果,它描述了关键点周围的图像特征。
6. 匹配关键点:
- 在检测到关键点及其描述子后,可以通过对比不同图像中的描述子,寻找相似的关键点以进行图像匹配。
过程:
- 通过最近邻匹配算法(如欧氏距离)将不同图像中的关键点描述子进行匹配。
SIFT 关键点检测总结流程:
- 高斯模糊与 DOG 差分:构建高斯金字塔,计算相邻尺度之间的差分,生成 DOG 金字塔。
- 极值检测:在 DOG 金字塔中检测局部极值点。
- 精确定位:拟合极值点,并去除低对比度或边缘上的关键点。
- 方向分配:为每个关键点分配一个主方向,使得关键点具有旋转不变性。
- 描述子生成:构建 128 维的特征描述子。
- 关键点匹配:通过特征描述子匹配不同图像中的关键点。
这个过程让 SIFT 能够在不同尺度、不同旋转角度下进行关键点检测和匹配,从而在图像匹配、特征识别中表现出强大的鲁棒性和稳定性。