Example #1
0
/**
Finds SIFT features in an image using user-specified parameter values.  All
detected features are stored in the array pointed to by \a feat.

@param img the image in which to detect features
@param fea a pointer to an array in which to store detected features
@param intvls the number of intervals sampled per octave of scale space
@param sigma the amount of Gaussian smoothing applied to each image level
	before building the scale space representation for an octave
@param cont_thr a threshold on the value of the scale space function
	\f$\left|D(\hat{x})\right|\f$, where \f$\hat{x}\f$ is a vector specifying
	feature location and scale, used to reject unstable features;  assumes
	pixel values in the range [0, 1]
@param curv_thr threshold on a feature's ratio of principle curvatures
	used to reject features that are too edge-like
@param img_dbl should be 1 if image doubling prior to scale space
	construction is desired or 0 if not
@param descr_width the width, \f$n\f$, of the \f$n \times n\f$ array of
	orientation histograms used to compute a feature's descriptor
@param descr_hist_bins the number of orientations in each of the
	histograms in the array used to compute a feature's descriptor

@return Returns the number of keypoints stored in \a feat or -1 on failure
@see sift_keypoints()
*/
int _sift_features( IplImage* img, struct feature** feat, int intvls,
				   double sigma, double contr_thr, int curv_thr,
				   int img_dbl, int descr_width, int descr_hist_bins )
{
	IplImage* init_img;
	IplImage*** gauss_pyr,***dog_pyr;
	CvMemStorage* storage;
	CvSeq* features;
	int octvs, i, n = 0;

	/* check arguments */
	if( ! img )
		fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );

	if( ! feat )
		fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );

	/* build scale space pyramid; smallest dimension of top level is ~4 pixels */
	init_img = create_init_img( img, img_dbl, sigma );
	octvs = log( MIN( init_img->width, init_img->height ) ) / log(2) - 2;
	gauss_pyr = build_gauss_pyr( init_img, octvs, intvls, sigma );
	dog_pyr = build_dog_pyr( gauss_pyr, octvs, intvls );

	storage = cvCreateMemStorage( 0 );
	//极值检测
	features = scale_space_extrema( dog_pyr, octvs, intvls, contr_thr,
		curv_thr, storage );
	//计算特征的尺度
	calc_feature_scales( features, sigma, intvls );
	//如果最先开始图像的尺寸被加倍了,那么调整features的参数
	if( img_dbl )
		adjust_for_img_dbl( features );
	//计算特征点方向和幅值
	calc_feature_oris( features, gauss_pyr );
	//计算特征描述子,最难理解的函数
	compute_descriptors( features, gauss_pyr, descr_width, descr_hist_bins );
	/* sort features by decreasing scale and move from CvSeq to array */
	cvSeqSort( features, (CvCmpFunc)feature_cmp, NULL );
	n = features->total;
	*feat = calloc( n, sizeof(struct feature) );
	*feat = cvCvtSeqToArray( features, *feat, CV_WHOLE_SEQ );//features 里面放的是feature* 数据,所以*feat而不是feat
	for( i = 0; i < n; i++ )//释放feature结构体中的feature_data,因为已经计算完了,得到了描述子
	{
		free( (*feat)[i].feature_data );
		(*feat)[i].feature_data = NULL;
	}

	cvReleaseMemStorage( &storage );
	cvReleaseImage( &init_img );
	release_pyr( &gauss_pyr, octvs, intvls + 3 );
	release_pyr( &dog_pyr, octvs, intvls + 2 );
	return n;
}
Example #2
0
/**
Finds SIFT features in an image using user-specified parameter values.  All
detected features are stored in the array pointed to by \a feat.

@param img the image in which to detect features
@param fea a pointer to an array in which to store detected features
@param intvls the number of intervals sampled per octave of scale space
@param sigma the amount of Gaussian smoothing applied to each image level
	before building the scale space representation for an octave
@param cont_thr a threshold on the value of the scale space function
	\f$\left|D(\hat{x})\right|\f$, where \f$\hat{x}\f$ is a vector specifying
	feature location and scale, used to reject unstable features;  assumes
	pixel values in the range [0, 1]
@param curv_thr threshold on a feature's ratio of principle curvatures
	used to reject features that are too edge-like
@param img_dbl should be 1 if image doubling prior to scale space
	construction is desired or 0 if not
@param descr_width the width, \f$n\f$, of the \f$n \times n\f$ array of
	orientation histograms used to compute a feature's descriptor
@param descr_hist_bins the number of orientations in each of the
	histograms in the array used to compute a feature's descriptor

@return Returns the number of keypoints stored in \a feat or -1 on failure
@see sift_keypoints()
*/
int _sift_features( IplImage* img, struct feature** feat, int intvls,
		   double sigma, double contr_thr, int curv_thr,
		   int img_dbl, int descr_width, int descr_hist_bins )
{
	IplImage *init_img;
	IplImage ***gauss_pyr, ***dog_pyr;
	CvMemStorage *storage;
	CvSeq *features;
	int octvs, i, n = 0;

	/* build scale space pyramid; smallest dimension of top level is ~4 pixels */
	init_img = create_init_img( img, img_dbl, sigma );
	octvs = log( MIN( init_img->width, init_img->height ) ) / log(2) - 2;
	gauss_pyr = build_gauss_pyr( init_img, octvs, intvls, sigma );
	dog_pyr = build_dog_pyr( gauss_pyr, octvs, intvls );

	storage = cvCreateMemStorage( 0 );
	features = scale_space_extrema( dog_pyr, octvs, intvls, contr_thr, curv_thr, storage );
	calc_feature_scales( features, sigma, intvls );
	if( img_dbl )
		adjust_for_img_dbl( features );
	calc_feature_oris( features, gauss_pyr );
	compute_descriptors( features, gauss_pyr, descr_width, descr_hist_bins );

	/* sort features by decreasing scale and move from CvSeq to array */
	cvSeqSort( features, (CvCmpFunc)feature_cmp, NULL );
	n = features->total;
	*feat = calloc( n, sizeof(struct feature) );
	*feat = cvCvtSeqToArray( features, *feat, CV_WHOLE_SEQ );
	for( i = 0; i < n; i++ ) {
		free( (*feat)[i].feature_data );
		(*feat)[i].feature_data = NULL;
	}

	cvReleaseMemStorage( &storage );
	cvReleaseImage( &init_img );
	release_pyr( &gauss_pyr, octvs, intvls + 3 );
	release_pyr( &dog_pyr, octvs, intvls + 2 );
	return n;
}
Example #3
0
/**
Finds SIFT features in an image using user-specified parameter values.  All
detected features are stored in the array pointed to by \a feat.

@param img the image in which to detect features
@param feat a pointer to an array in which to store detected features
@param intvls the number of intervals sampled per octave of scale space
@param sigma the amount of Gaussian smoothing applied to each image level
	before building the scale space representation for an octave
@param cont_thr a threshold on the value of the scale space function
	\f$\left|D(\hat{x})\right|\f$, where \f$\hat{x}\f$ is a vector specifying
	feature location and scale, used to reject unstable features;  assumes
	pixel values in the range [0, 1]
@param curv_thr threshold on a feature's ratio of principle curvatures
	used to reject features that are too edge-like
@param img_dbl should be 1 if image doubling prior to scale space
	construction is desired or 0 if not
@param descr_width the width, \f$n\f$, of the \f$n \times n\f$ array of
	orientation histograms used to compute a feature's descriptor
@param descr_hist_bins the number of orientations in each of the
	histograms in the array used to compute a feature's descriptor

@return Returns the number of keypoints stored in \a feat or -1 on failure
@see sift_keypoints()
*/
int _sift_features( IplImage* img, struct feature** feat, int intvls,
				   double sigma, double contr_thr, int curv_thr,
				   int img_dbl, int descr_width, int descr_hist_bins )
{
    IplImage* init_img;//原图经初始化后的图像,归一化的32位灰度图
    IplImage*** gauss_pyr, *** dog_pyr;//三级指针,高斯金字塔图像组,DoG金字塔图像组
    CvMemStorage* storage;//存储器
    CvSeq* features;//存储特征点的序列,序列中存放的是struct feature类型的指针
	int octvs, i, n = 0;

    //输入参数检查
	/* check arguments */
	if( ! img )
		fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );

	if( ! feat )
		fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );

	/* build scale space pyramid; smallest dimension of top level is ~4 pixels */

    //██步骤一:██:建立尺度空间,即建立高斯差分(DoG)金字塔dog_pyr
    //将原图转换为32位灰度图并归一化,然后进行一次高斯平滑,并根据参数img_dbl决定是否将图像尺寸放大为原图的2倍
	init_img = create_init_img( img, img_dbl, sigma );
    //计算高斯金字塔的组数octvs
    octvs = log( MIN( init_img->width, init_img->height ) ) / log(2) - 2;
    //为了保证连续性,在每一层的顶层继续用高斯模糊生成3幅图像,所以高斯金字塔每组有intvls+3层,DOG金字塔每组有intvls+2层
    //建立高斯金字塔gauss_pyr,是一个octvs*(intvls+3)的图像数组
	gauss_pyr = build_gauss_pyr( init_img, octvs, intvls, sigma );
    //建立高斯差分(DoG)金字塔dog_pyr,是一个octvs*(intvls+2)的图像数组
	dog_pyr = build_dog_pyr( gauss_pyr, octvs, intvls );

    //██步骤二:██:在尺度空间中检测极值点,并进行精确定位和筛选
    //创建默认大小的内存存储器
	storage = cvCreateMemStorage( 0 );
    //在尺度空间中检测极值点,通过插值精确定位,去除低对比度的点,去除边缘点,返回检测到的特征点序列
    features = scale_space_extrema( dog_pyr, octvs, intvls, contr_thr, curv_thr, storage );
    //计算特征点序列features中每个特征点的尺度
	calc_feature_scales( features, sigma, intvls );
    //若设置了将图像放大为原图的2倍
    if( img_dbl )//将特征点序列中每个特征点的坐标减半(当设置了将图像放大为原图的2倍时,特征点检测完之后调用)
		adjust_for_img_dbl( features );

    //██步骤三:██:特征点方向赋值,完成此步骤后,每个特征点有三个信息:位置、尺度、方向
    //计算每个特征点的梯度直方图,找出其主方向,若一个特征点有不止一个主方向,将其分为两个特征点
	calc_feature_oris( features, gauss_pyr );

    //██步骤四:██:计算特征描述子
    //计算特征点序列中每个特征点的特征描述子向量
	compute_descriptors( features, gauss_pyr, descr_width, descr_hist_bins );

	/* sort features by decreasing scale and move from CvSeq to array */
    //按特征点尺度的降序排列序列中元素的顺序,feature_cmp是自定义的比较函数
	cvSeqSort( features, (CvCmpFunc)feature_cmp, NULL );

    //将CvSeq类型的特征点序列features转换为通用的struct feature类型的数组feat
    n = features->total;//特征点个数
    *feat = calloc( n, sizeof(struct feature) );//分配控件
    //将序列features中的元素拷贝到数组feat中,返回数组指针给feat
	*feat = cvCvtSeqToArray( features, *feat, CV_WHOLE_SEQ );

    //释放特征点数组feat中所有特征点的feature_data成员,因为此成员中的数据在检测完特征点后就没用了
	for( i = 0; i < n; i++ )
	{
		free( (*feat)[i].feature_data );
		(*feat)[i].feature_data = NULL;
	}

    //释放各种临时数据的存储空间
    cvReleaseMemStorage( &storage );//释放内存存储器
    cvReleaseImage( &init_img );//释放初始化后的图像
    release_pyr( &gauss_pyr, octvs, intvls + 3 );//释放高斯金字塔图像组
    release_pyr( &dog_pyr, octvs, intvls + 2 );//释放高斯差分金字塔图像组

    return n;//返回检测到的特征点的个数
}