sift算法主程序详解——转载

最近也一直在研究SIFT(尺度不变特征匹配算法),先理解算法的数学原理,然后再一步步分析Rob Hess的程序代码:


//初始值为3
#define SIFT_INTVLS 3


//初始值是1.6
#define SIFT_SIGMA 1.6


// 值越大,被剔除的特征点就越多
#define SIFT_CONTR_THR 0.04
//初始值是0.04


//主曲率阈值r=10,大于10即去掉边缘响应点
#define SIFT_CURV_THR 10
//初始值是10


//在建立尺度空间之前如果原图像放大一倍则取值为1,否则为0
#define SIFT_IMG_DBL 1


//descr_width:计算特征描述符时邻域子块的宽度,
#define SIFT_DESCR_WIDTH 4
//初始值为4


//计算特征描述符时将特征点邻域进行投影的方向数,默认为8,分别是0,45,90,135 180,225,270,315共8个方向。
#define SIFT_DESCR_HIST_BINS 8


#define SIFT_INIT_SIGMA 0.5
//初始值是0.5


//忽略特征点的边界宽度
#define SIFT_IMG_BORDER 5


#define SIFT_MAX_INTERP_STEPS 5


#define SIFT_ORI_HIST_BINS 36


//特征点主方向分配时高斯平滑σ为1.5倍特征点所在的尺度
#define SIFT_ORI_SIG_FCTR 1.5


//主方向分配时使用的区域半径
#define SIFT_ORI_RADIUS 3.0 * SIFT_ORI_SIG_FCTR


#define SIFT_ORI_SMOOTH_PASSES 2


//初始值0.8 阈值
#define SIFT_ORI_PEAK_RATIO 0.8


//初始值3.0
#define SIFT_DESCR_SCL_FCTR 3.0


//初始值是0.2 128维SIFT描述子中大于0.2的维度量截取为0.2
#define SIFT_DESCR_MAG_THR 0.2


//浮点数转换为无符号字符的因子值
#define SIFT_INT_DESCR_FCTR 512.0


#define feat_detection_data(f) ( (struct detection_data*)(f->feature_data) )

 

特征点检测函数分析

int sift_features( IplImage* img, struct feature** feat )
{
 return _sift_features( img, feat, SIFT_INTVLS, SIFT_SIGMA, SIFT_CONTR_THR,
       SIFT_CURV_THR, SIFT_IMG_DBL, SIFT_DESCR_WIDTH,
       SIFT_DESCR_HIST_BINS );
}


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; //CvSeq定义非固定元素的序列
 int octvs, i, n = 0;

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

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

 
 init_img = create_init_img( img, img_dbl, sigma ); //将图像转为8位灰度图像,然后再高斯平滑
 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 ); //构建DOG尺度空间

 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 );//

 
 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值