Пример #1
0
/*
Computes a canonical orientation for each image feature in an array.  Based
on Section 5 of Lowe's paper.  This function adds features to the array when
there is more than one dominant orientation at a given feature location.

@param features an array of image features
@param gauss_pyr Gaussian scale space pyramid
*/
static void calc_feature_oris( CvSeq* features, IplImage*** gauss_pyr )
{
	struct feature* feat;
	struct detection_data* ddata;
	double* hist;
	double omax;
	int i, j, n = features->total;

	for( i = 0; i < n; i++ )
	{
		feat = malloc( sizeof( struct feature ) );
		cvSeqPopFront( features, feat );
		ddata = feat_detection_data( feat );
		/*Each sample added to the hstogram is weighted by its gradient magnitude and by a gausian-weighted circular 
		window with a sigma that is 1.5 times that of the scale of the keypoint*/
		hist = ori_hist( gauss_pyr[ddata->octv][ddata->intvl],
						ddata->r, ddata->c, SIFT_ORI_HIST_BINS,
						cvRound( SIFT_ORI_RADIUS * ddata->scl_octv ),//主方向分配时使用的区域半径
						SIFT_ORI_SIG_FCTR * ddata->scl_octv );//特征点主方向分配时高斯平滑σ为1.5倍特征点所在的尺度
		for( j = 0; j < SIFT_ORI_SMOOTH_PASSES; j++ )
			smooth_ori_hist( hist, SIFT_ORI_HIST_BINS );//使用高斯函数对直方图进行平滑,减少突变的影响
		omax = dominant_ori( hist, SIFT_ORI_HIST_BINS );//在直方图中找到主方向的梯度
		add_good_ori_features( features, hist, SIFT_ORI_HIST_BINS,//将大于某一个梯度大小阈值的特征向量加入到直方图中去
								omax * SIFT_ORI_PEAK_RATIO, feat );
		free( ddata );
		free( feat );
		free( hist );
	}
}
Пример #2
0
/*
Computes a canonical orientation for each image feature in an array.  Based
on Section 5 of Lowe's paper.  This function adds features to the array when
there is more than one dominant orientation at a given feature location.

@param features an array of image features
@param gauss_pyr Gaussian scale space pyramid
*/
void calc_feature_oris( CvSeq* features, IplImage*** gauss_pyr )
{
	struct feature* feat;
	struct detection_data* ddata;
	double* hist;
	double omax;
	int i, j, n = features->total;

	for( i = 0; i < n; i++ )
	{
		feat = (feature* )malloc( sizeof( struct feature ) );
		cvSeqPopFront( features, feat );
		ddata = feat_detection_data( feat );
		hist = ori_hist( gauss_pyr[ddata->octv][ddata->intvl],
						ddata->r, ddata->c, SIFT_ORI_HIST_BINS,
						cvRound( SIFT_ORI_RADIUS * ddata->scl_octv ),
						SIFT_ORI_SIG_FCTR * ddata->scl_octv );
		for( j = 0; j < SIFT_ORI_SMOOTH_PASSES; j++ )
			smooth_ori_hist( hist, SIFT_ORI_HIST_BINS );
		omax = dominant_ori( hist, SIFT_ORI_HIST_BINS );
		add_good_ori_features( features, hist, SIFT_ORI_HIST_BINS,
								omax * SIFT_ORI_PEAK_RATIO, feat );
		free( ddata );
		free( feat );
		free( hist );
	}
}
Пример #3
0
/*
Computes a canonical orientation for each image feature in an array.  Based
on Section 5 of Lowe's paper.  This function adds features to the array when
there is more than one dominant orientation at a given feature location.
@param features an array of image features
@param gauss_pyr Gaussian scale space pyramid
*/
static void calc_feature_oris( CvSeq* features, IplImage*** gauss_pyr )
{
	struct feature* feat;
	struct detection_data* ddata;
    double* hist;//存放梯度直方图的数组
	double omax;
    int i, j, n = features->total;//特征点个数

    //遍历特征点序列
	for( i = 0; i < n; i++ )
	{
        //给每个特征点分配feature结构大小的内存
		feat = malloc( sizeof( struct feature ) );
        //移除列首元素,放到feat中
		cvSeqPopFront( features, feat );
        //调用宏feat_detection_data来提取参数feat中的feature_data成员并转换为detection_data类型的指针
        //detection_data数据中存放有此特征点的行列坐标和尺度,以及所在的层和组
		ddata = feat_detection_data( feat );

        //计算指定像素点的梯度方向直方图,返回存放直方图的数组给hist
        hist = ori_hist( gauss_pyr[ddata->octv][ddata->intvl],       //特征点所在的图像
                        ddata->r, ddata->c,                          //特征点的行列坐标
                        SIFT_ORI_HIST_BINS,                          //默认的梯度直方图的bin(柱子)个数
                        cvRound( SIFT_ORI_RADIUS * ddata->scl_octv ),//特征点方向赋值过程中,搜索邻域的半径为:3 * 1.5 * σ
                        SIFT_ORI_SIG_FCTR * ddata->scl_octv );       //计算直翻图时梯度幅值的高斯权重的初始值

        //对梯度直方图进行高斯平滑,弥补因没有仿射不变性而产生的特征点不稳定的问题,SIFT_ORI_SMOOTH_PASSES指定了平滑次数
		for( j = 0; j < SIFT_ORI_SMOOTH_PASSES; j++ )
			smooth_ori_hist( hist, SIFT_ORI_HIST_BINS );

        //查找梯度直方图中主方向的梯度幅值,即查找直方图中最大bin的值,返回给omax
		omax = dominant_ori( hist, SIFT_ORI_HIST_BINS );
        /*若当前特征点的直方图中某个bin的值大于给定的阈值,则新生成一个特征点并添加到特征点序列末尾
          传入的特征点指针feat是已经从特征点序列features中移除的,所以即使此特征点没有辅方向(第二个大于幅值阈值的方向)
          在函数add_good_ori_features中也会执行一次克隆feat,对其方向进行插值修正,并插入特征点序列的操作
          幅值阈值一般设置为当前特征点的梯度直方图的最大bin值的80%                   */
		add_good_ori_features( features, hist, SIFT_ORI_HIST_BINS,
								omax * SIFT_ORI_PEAK_RATIO, feat );
        //释放内存
		free( ddata );
		free( feat );
		free( hist );
	}
}