SIFT特征点检测
刚看完了SIFT特征点检测的原理,阅读的是两篇csdn博客,一个全面和一个最全面,不得不说,你俩写的都很全面,这么用心奉献知识的博主是全人类的财富。
现在用我这张笨拙的嘴先说一下我理解的流程
首先先将图像扩大一倍,David Lowe 使用了 双三次插值(Bicubic Interpolation) 来将原图像扩大一倍。
用不同尺度的高斯核对这个扩大一倍的图像做平滑操作。将第1组倒数第三层图像作比例因子为2的降采样(隔点采样)(这里取倒数第三层可能因为倒数第三层能够检测到足够多的特征点,更适合进行下采样)
SIFT算法的目标是构建一个尺度空间,用于检测尺度不变的特征点。尺度空间通常由多个组(octave)和多个层(scale level)组成。每个组包含一系列逐渐平滑的图像,每个层对应于不同的尺度。
组(Octave):每个组的图像分辨率不同,通常通过降采样实现。
层(Scale Level):每个组内的图像通过高斯平滑实现不同尺度的表示。
然后将同一组的不同层的图像做差分,得到高斯差分金字塔(DOG)。特征点是由DOG空间的局部极值点组成的。为了寻找DoG函数的极值点,每一个像素点要和它所有的相邻点比较,看其是否比它的图像域和尺度域的相邻点大或者小,在高斯差分金字塔中寻找极值点,除了考虑x,y方向的点,还要考虑σ(尺度) 方向的点,所以判断一个像素点是否为极值点,要与周围的26个点(一组有六个层的话就生成五个差分图像,在中间三层中寻找极值点,9*2+8=26)进行比较,找到极值点。
局部极大值或极小值点代表了图像中的显著特征,如角点、边缘等。 这些特征点在不同尺度下具有稳定的几何和强度特性,因此可以用于图像的匹配和识别。
注: ① 如果高斯差分金字塔每组有3层,则只能在中间1层图像寻 找极值点, 两端的图像不连续,没有极值点.
② 如果高斯差分金字塔每组有5层,则只能在中间3层图像寻找极值点.
DoG图像中的局部极大值或极小值点。这些点是通过离散采样得到的,可能存在一定的误差,泰勒展开式可以将DoG函数在特征点附近展开为一个二次多项式,从而得到特征点的精确位置。
然后
1.在关键点周围的一个邻域内(通常是 15σ 的范围),计算每个像素的梯度方向和大小。
2.将梯度方向分成若干个方向区间(通常为36个方向,每10度一个区间),统计每个方向的梯度大小总和。选择梯度方向直方图中的最大值对应的方向作为关键点的主方向。
3.将关键点邻域旋转,使得主方向指向水平方向(通常是x轴方向)。这样,即使图像本身旋转,描述子仍然保持一致。
4.划分子区域
将关键点邻域划分为 4×4 的网格,每个网格对应一个子区域。通常以关键点为中心,取一个 16σ×16σ 的邻域。
子区域大小:每个子区域的大小为 4σ×4σ。
4.1 统计梯度方向直方图
在每个子区域内,计算每个像素的梯度方向和大小。
4.2 将梯度方向分成8个方向区间(每45度一个区间),统计每个方向的梯度大小总和。每个子区域生成一个8维的梯度方向直方图。
4.3 生成描述子
将 4×4 的子区域的梯度方向直方图合并,得到一个 4×4×8=128 维的特征向量。
5. 归一化:为了增强描述子的鲁棒性,对特征向量进行归一化处理。
第一次归一化:将特征向量的长度归一化到1。
5.1 截断:将特征向量中大于0.2的值截断为0.2,以减少光照变化和边缘效应的影响。
5.2 第二次归一化:再次将截断后的特征向量归一化到长度为1。
截断:将特征向量中大于0.2的值截断为0.2,进一步增强描述子的鲁棒性。这是因为过大的梯度值可能由噪声或边缘效应引起,截断可以减少这些影响。
目标的识别是通过两点集内关键点描述子的比对来完成。具有128维的关键点描述子的相似性度量采用欧式距离。
匹配可采取穷举法完成,但所花费的时间太多。所以一般采用kd树的数据结构来完成搜索。搜索的内容是以目标图像的关键点为基准,搜索与目标图像的特征点最邻近的原图像特征点和次邻近的原图像特征点。