《SIFT原理与源码分析》系列文章索引:http://blog.csdn.net/xiaowei_cqu/article/details/8069548
由前一步《DoG尺度空间构造》,我们得到了DoG高斯差分金字塔:
如上图的金字塔,高斯尺度空间金字塔中每组有五层不同尺度图像,相邻两层相减得到四层DoG结果。关键点搜索就在这四层DoG图像上寻找局部极值点。
DoG局部极值点
寻找DoG极值点时,每一个像素点和它所有的相邻点比较,当其大于(或小于)它的图像域和尺度域的所有相邻点时,即为极值点。如下图所示,比较的范围是个3×3的立方体:中间的检测点和它同尺度的8个相邻点,以及和上下相邻尺度对应的9×2个点——共26个点比较,以确保在尺度空间和二维图像空间都检测到极值点。
在一组中,搜索从每组的第二层开始,以第二层为当前层,第一层和第三层分别作为立方体的的上下层;搜索完成后再以第三层为当前层做同样的搜索。所以每层的点搜索两次。通常我们将组Octaves索引以-1开始,则在比较时牺牲了-1组的第0层和第N组的最高层
高斯金字塔,DoG图像及极值计算的相互关系如上图所示。
关键点精确定位
以上极值点的搜索是在离散空间进行搜索的,由下图可以看到,在离散空间找到的极值点不一定是真正意义上的极值点。可以通过对尺度空间DoG函数进行曲线拟合寻找极值点来减小这种误差。
![](https://img-my.csdn.net/uploads/201210/19/1350655887_3551.png)
利用DoG函数在尺度空间的Taylor展开式:
![](https://img-my.csdn.net/uploads/201210/19/1350654378_6893.png)
则极值点为:
![](https://img-my.csdn.net/uploads/201210/19/1350654391_8072.png)
程序中还除去了极值小于0.04的点。如下所示:
// Detects features at extrema in DoG scale space. Bad features are discarded
// based on contrast and ratio of principal curvatures.
// 在DoG尺度空间寻特征点(极值点)
void SIFT::findScaleSpaceExtrema( const vector<Mat>& gauss_pyr, const vector<Mat>& dog_pyr,
vector<KeyPoint>& keypoints ) const
{
int nOctaves = (int)gauss_pyr.size()/(nOctaveLayers + 3);
// The contrast threshold used to filter out weak features in semi-uniform
// (low-contrast) regions. The larger the threshold, the less features are produced by the detector.
// 过滤掉弱特征的阈值 contrastThreshold默认为0.04
int threshold = cvFloor(0.5 * contrastThreshold / nOctaveLayers * 255 * SIFT_FIXPT_SCALE);
const int n = SIFT_ORI_HIST_BINS; //36
float hist[n];
KeyPoint kpt;
keypoints.clear();
for( int o = 0; o < nOctaves; o++ )
for(