/* Detects features at extrema in DoG scale space. Bad features are discarded based on contrast and ratio of principal curvatures. @param dog_pyr DoG scale space pyramid @param octvs octaves of scale space represented by dog_pyr @param intvls intervals per octave @param contr_thr low threshold on feature contrast @param curv_thr high threshold on feature ratio of principal curvatures @param storage memory storage in which to store detected features @return Returns an array of detected features whose scales, orientations, and descriptors are yet to be determined. */ CvSeq* scale_space_extrema( IplImage*** dog_pyr, int octvs, int intvls, double contr_thr, int curv_thr, CvMemStorage* storage ) { CvSeq* features; double prelim_contr_thr = 0.5 * contr_thr / intvls; struct feature* feat; struct detection_data* ddata; int o, i, r, c; features = cvCreateSeq( 0, sizeof(CvSeq), sizeof(struct feature), storage ); for( o = 0; o < octvs; o++ ) for( i = 1; i <= intvls; i++ ) for(r = SIFT_IMG_BORDER; r < dog_pyr[o][0]->height-SIFT_IMG_BORDER; r++) for(c = SIFT_IMG_BORDER; c < dog_pyr[o][0]->width-SIFT_IMG_BORDER; c++) /* perform preliminary check on contrast */ if( ABS( pixval32f( dog_pyr[o][i], r, c ) ) > prelim_contr_thr ) if( is_extremum( dog_pyr, o, i, r, c ) ) { feat = interp_extremum(dog_pyr, o, i, r, c, intvls, contr_thr); if( feat ) { ddata = feat_detection_data( feat ); if( ! is_too_edge_like( dog_pyr[ddata->octv][ddata->intvl], ddata->r, ddata->c, curv_thr ) ) { cvSeqPush( features, feat ); } else free( ddata ); free( feat ); } } return features; }
/* Detects features at extrema in DoG scale space. Bad features are discarded based on contrast and ratio of principal curvatures. @param dog_pyr DoG scale space pyramid @param octvs octaves of scale space represented by dog_pyr @param intvls intervals per octave @param contr_thr low threshold on feature contrast @param curv_thr high threshold on feature ratio of principal curvatures @param storage memory storage in which to store detected features @return Returns an array of detected features whose scales, orientations, and descriptors are yet to be determined. */ static CvSeq* scale_space_extrema( IplImage*** dog_pyr, int octvs, int intvls, double contr_thr, int curv_thr, CvMemStorage* storage ) { CvSeq* features;//特征点序列 double prelim_contr_thr = 0.5 * contr_thr / intvls;//像素的对比度阈值 struct feature* feat; struct detection_data* ddata; int o, i, r, c; //在存储器storage上创建存储极值点的序列,其中存储feature结构类型的数据 features = cvCreateSeq( 0, sizeof(CvSeq), sizeof(struct feature), storage ); /*遍历高斯差分金字塔,检测极值点*/ //SIFT_IMG_BORDER指明边界宽度,只检测边界线以内的极值点 for( o = 0; o < octvs; o++ )//第o组 for( i = 1; i <= intvls; i++ )//遍i层 for(r = SIFT_IMG_BORDER; r < dog_pyr[o][0]->height-SIFT_IMG_BORDER; r++)//第r行 for(c = SIFT_IMG_BORDER; c < dog_pyr[o][0]->width-SIFT_IMG_BORDER; c++)//第c列 //进行初步的对比度检查,只有当归一化后的像素值大于对比度阈值prelim_contr_thr时才继续检测此像素点是否可能是极值 //调用函数pixval32f获取图像dog_pyr[o][i]的第r行第c列的点的坐标值,然后调用ABS宏求其绝对值 if( ABS( pixval32f( dog_pyr[o][i], r, c ) ) > prelim_contr_thr ) //通过在尺度空间中将一个像素点的值与其周围3*3*3邻域内的点比较来决定此点是否极值点(极大值或极小都行) if( is_extremum( dog_pyr, o, i, r, c ) )//若是极值点 { //由于极值点的检测是在离散空间中进行的,所以检测到的极值点并不一定是真正意义上的极值点 //因为真正的极值点可能位于两个像素之间,而在离散空间中只能精确到坐标点精度上 //通过亚像素级插值进行极值点精确定位(修正极值点坐标),并去除低对比度的极值点,将修正后的特征点组成feature结构返回 feat = interp_extremum(dog_pyr, o, i, r, c, intvls, contr_thr); //返回值非空,表明此点已被成功修正 if( feat ) { //调用宏feat_detection_data来提取参数feat中的feature_data成员并转换为detection_data类型的指针 ddata = feat_detection_data( feat ); //去除边缘响应,即通过计算主曲率比值判断某点是否边缘点,返回值为0表示不是边缘点,可做特征点 if( ! is_too_edge_like( dog_pyr[ddata->octv][ddata->intvl], ddata->r, ddata->c, curv_thr ) ) { cvSeqPush( features, feat );//向特征点序列features末尾插入新检测到的特征点feat } else free( ddata ); free( feat ); } } return features;//返回特征点序列 }