实际方案:DoG# LoG 的理论很好但就和 Harris 为什么要对结构张量进行工程优化一样其计算代价相当高。因此我们在实际工程中使用的是其近似版本高斯差分Difference of GaussianDoG对于尺度空间如果取两个相邻尺度和直接做差看起来只是简单相减但根据尺度空间理论可以证明也就是说它实际上近似于尺度归一化后的 LoG这也是 SIFT 中真正使用的方法在下面的具体步骤中我们就可以看到它的位置。5. SIFT 特征点检测#下面就开始 SIFT 的实际构建了这部分逻辑十分复杂步骤也较多但可以说是最标准化的流程后续的几个出名算法其实本质上就是针对不同目标对 SIFT 的简化改进。5.1 DoG 金字塔#一个很明显的道理是尺度空间不可能无限大如果一直增大 图像最终会被模糊成一团灰色继续计算没有意义。因此 SIFT 采用了一个方法当尺度增大到一定程度后不再继续增大 而是直接缩小图像。一个需要注意的是原论文中原始图像在开始处理前会先通过插值放大一倍来进行更密集的采样而随着现代成像技术的提升这点并不强制了。回到主线假如尺寸为 1024×1024 的初始图在处理中会逐渐减小到 512×512再到 256×256、128×128 等。而这样做的效果其实与继续增大尺度非常接近。假设图像中有一个半径 的圆斑在初始图中它占据很大面积但如果直接缩小图像一半那么圆斑半径也变成 相当于目标自动变小了。其核心逻辑是目标变小与检测器变大本质上都是在改变二者的相对尺度。这便形成了 SIFT 的金字塔结构其中存在两个核心设计Octave和Interval。SIFT 将尺度空间划分成多个组每个组称为一个Octave八度。每经过一个 Octave图像尺寸缩小一半这样整个尺度空间被分解成多个层级小尺度特征主要在前几个 Octave 中检测而大尺度特征则在后几个 Octave 中检测。但仅有 Octave 还不够因为同一个 Octave 内仍然需要搜索最佳尺度所以每个 Octave 内还会划分多个Interval尺度间隔。原论文中设注意这里的 并不是后面马上要提到的 Gaussian 层数或者 DoG 层数而是和下一部分检测有关它是指一个 Octave 中真正参与尺度搜索的 Interval 数量。展开来说为了让一个 Octave 恰好覆盖尺度翻倍我们定义一个尺度倍率当 时因此尺度会按照如下方式增长例如初始尺度取 则对应层号01.6012.0222.5433.20这样便定义出了一个 Octave 中的尺度划分方式。接下来需要构建对应的高斯图像如果只考虑这 3 个 Interval那么理论上只需要生成对应尺度的 Gaussian 图像即可。但后面还需要构建 DoG 图像并进行三维尺度空间极值检测因此SIFT 会额外生成若干高斯层作为边界缓冲。最终每个 Octave 实际会生成个 Gaussian 图像。当 时生成结果就如下Gaussian层作用1.60有效尺度层2.02有效尺度层2.54有效尺度层3.20有效尺度层达到 也是下一 Octave 的起始来源4.03边界缓冲层用于构建 DoG5.08边界缓冲层用于构建 DoG 与极值检测最终多个 Octave 的 Gaussian 图像共同组成高斯金字塔Gaussian Pyramid。得到高斯金字塔后在每个 Octave 内对相邻 Gaussian 图像做差例如Gaussian层Gaussian尺度DoG层DoG对应尺度--一般情况下个个而这些 DoG 图像会共同组成DoG 金字塔Difference of Gaussian Pyramid。之所以需要额外生成两层 DoG是因为后面寻找极值点时需要同时比较当前层、上一层和下一层总计 的三维邻域。最顶层和最底层 DoG 无法参与极值检测只能作为边界层存在这样以来最终真正参与尺度空间搜索的 DoG 层数恰好为这也正好对应最开始设定的 Interval 数量这样我们就完成了极值检测的所有准备。5.2 尺度空间极值检测#这一步相对简单得到 DoG 金字塔后其最顶层和最底层 DoG 不参与检测假设当前考察点位于现在这个点周围有当前层 8 个邻居、上一层 9 个邻居以及下一层 9 个邻居总计26个邻居。SIFT 要求当前点必须同时大于或小于全部 26 个邻居。遍历整个金字塔这样的点才能被保留。这一步就是尺度空间极值检测Scale Space Extrema Detection也就是说只有中心点同时成为空间和尺度两个方向上的极值才能成为候选关键点。此时得到的结果已经包含了 前两维说明位置显著第三维说明尺度显著并且我们还可以通过尺度系数和检测器大小的关系估计出特征尺寸。到这里我们已经成功提取出了候选关键点但 SIFT 仍然还有相当一部分内容我们继续。5.3 关键点精确定位#现在我们已经获得了一批候选关键点但这里有一个问题DoG 金字塔本质上是离散采样的尺度空间而真实极值点的位置并不一定刚好落在采样网格上。比如某个位置附近的 DoG 响应如下