⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sift.c

📁 Rob Hess Linux下的SIFT提取源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  Functions for detecting SIFT image features.    For more information, refer to:    Lowe, D.  Distinctive image features from scale-invariant keypoints.  <EM>International Journal of Computer Vision, 60</EM>, 2 (2004),  pp.91--110.    Copyright (C) 2006-2007  Rob Hess <hess@eecs.oregonstate.edu>  Note: The SIFT algorithm is patented in the United States and cannot be  used in commercial products without a license from the University of  British Columbia.  For more information, refer to the file LICENSE.ubc  that accompanied this distribution.  @version 1.1.1-20070913*/#include "sift.h"#include "imgfeatures.h"#include "utils.h"#include <cxcore.h>#include <cv.h>/************************* Local Function Prototypes *************************/IplImage* create_init_img( IplImage*, int, double );IplImage* convert_to_gray32( IplImage* );IplImage*** build_gauss_pyr( IplImage*, int, int, double );IplImage* downsample( IplImage* );IplImage*** build_dog_pyr( IplImage***, int, int );CvSeq* scale_space_extrema( IplImage***, int, int, double, int, CvMemStorage*);int is_extremum( IplImage***, int, int, int, int );struct feature* interp_extremum( IplImage***, int, int, int, int, int, double);void interp_step( IplImage***, int, int, int, int, double*, double*, double* );CvMat* deriv_3D( IplImage***, int, int, int, int );CvMat* hessian_3D( IplImage***, int, int, int, int );double interp_contr( IplImage***, int, int, int, int, double, double, double );struct feature* new_feature( void );int is_too_edge_like( IplImage*, int, int, int );void calc_feature_scales( CvSeq*, double, int );void adjust_for_img_dbl( CvSeq* );void calc_feature_oris( CvSeq*, IplImage*** );double* ori_hist( IplImage*, int, int, int, int, double );int calc_grad_mag_ori( IplImage*, int, int, double*, double* );void smooth_ori_hist( double*, int );double dominant_ori( double*, int );void add_good_ori_features( CvSeq*, double*, int, double, struct feature* );struct feature* clone_feature( struct feature* );void compute_descriptors( CvSeq*, IplImage***, int, int );double*** descr_hist( IplImage*, int, int, double, double, int, int );void interp_hist_entry( double***, double, double, double, double, int, int);void hist_to_descr( double***, int, int, struct feature* );void normalize_descr( struct feature* );int feature_cmp( void*, void*, void* );void release_descr_hist( double****, int );void release_pyr( IplImage****, int, int );/*********************** Functions prototyped in sift.h **********************//**   Finds SIFT features in an image using default 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   @return Returns the number of features stored in \a feat or -1 on failure   @see _sift_features()*/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 );}/**   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 );  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;}/************************ Functions prototyped here **************************//*  Converts an image to 8-bit grayscale and Gaussian-smooths it.  The image is  optionally doubled in size prior to smoothing.  @param img input image  @param img_dbl if true, image is doubled in size prior to smoothing  @param sigma total std of Gaussian smoothing*/IplImage* create_init_img( IplImage* img, int img_dbl, double sigma ){  IplImage* gray, * dbl;  double sig_diff;  gray = convert_to_gray32( img );  if( img_dbl )    {      sig_diff = sqrt( sigma * sigma - SIFT_INIT_SIGMA * SIFT_INIT_SIGMA * 4 );      dbl = cvCreateImage( cvSize( img->width*2, img->height*2 ),			   IPL_DEPTH_32F, 1 );      cvResize( gray, dbl, CV_INTER_CUBIC );      cvSmooth( dbl, dbl, CV_GAUSSIAN, 0, 0, sig_diff, sig_diff );      cvReleaseImage( &gray );      return dbl;    }  else    {      sig_diff = sqrt( sigma * sigma - SIFT_INIT_SIGMA * SIFT_INIT_SIGMA );      cvSmooth( gray, gray, CV_GAUSSIAN, 0, 0, sig_diff, sig_diff );      return gray;    }}/*  Converts an image to 32-bit grayscale  @param img a 3-channel 8-bit color (BGR) or 8-bit gray image  @return Returns a 32-bit grayscale image*/IplImage* convert_to_gray32( IplImage* img ){  IplImage* gray8, * gray32;  gray8 = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );  gray32 = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );  if( img->nChannels == 1 )    gray8 = cvClone( img );  else    cvCvtColor( img, gray8, CV_BGR2GRAY );  cvConvertScale( gray8, gray32, 1.0 / 255.0, 0 );  cvReleaseImage( &gray8 );  return gray32;}/*  Builds Gaussian scale space pyramid from an image  @param base base image of the pyramid  @param octvs number of octaves of scale space  @param intvls number of intervals per octave  @param sigma amount of Gaussian smoothing per octave  @return Returns a Gaussian scale space pyramid as an octvs x (intvls + 3)    array*/IplImage*** build_gauss_pyr( IplImage* base, int octvs,			     int intvls, double sigma ){  IplImage*** gauss_pyr;  const int _intvls = intvls;  double sig[_intvls+3], sig_total, sig_prev, k;  int i, o;  gauss_pyr = calloc( octvs, sizeof( IplImage** ) );  for( i = 0; i < octvs; i++ )    gauss_pyr[i] = calloc( intvls + 3, sizeof( IplImage *) );  /*    precompute Gaussian sigmas using the following formula:    \sigma_{total}^2 = \sigma_{i}^2 + \sigma_{i-1}^2  */  sig[0] = sigma;  k = pow( 2.0, 1.0 / intvls );  for( i = 1; i < intvls + 3; i++ )    {      sig_prev = pow( k, i - 1 ) * sigma;      sig_total = sig_prev * k;      sig[i] = sqrt( sig_total * sig_total - sig_prev * sig_prev );    }  for( o = 0; o < octvs; o++ )    for( i = 0; i < intvls + 3; i++ )      {	if( o == 0  &&  i == 0 )	  gauss_pyr[o][i] = cvCloneImage(base);	/* base of new octvave is halved image from end of previous octave */	else if( i == 0 )	  gauss_pyr[o][i] = downsample( gauss_pyr[o-1][intvls] );	  	/* blur the current octave's last image to create the next one */	else	  {	    gauss_pyr[o][i] = cvCreateImage( cvGetSize(gauss_pyr[o][i-1]),					     IPL_DEPTH_32F, 1 );	    cvSmooth( gauss_pyr[o][i-1], gauss_pyr[o][i],		      CV_GAUSSIAN, 0, 0, sig[i], sig[i] );	  }      }  return gauss_pyr;}/*  Downsamples an image to a quarter of its size (half in each dimension)  using nearest-neighbor interpolation  @param img an image  @return Returns an image whose dimensions are half those of img*/IplImage* downsample( IplImage* img ){  IplImage* smaller = cvCreateImage( cvSize(img->width / 2, img->height / 2),				     img->depth, img->nChannels );  cvResize( img, smaller, CV_INTER_NN );  return smaller;}/*  Builds a difference of Gaussians scale space pyramid by subtracting adjacent  intervals of a Gaussian pyramid  @param gauss_pyr Gaussian scale-space pyramid  @param octvs number of octaves of scale space  @param intvls number of intervals per octave  @return Returns a difference of Gaussians scale space pyramid as an    octvs x (intvls + 2) array*/IplImage*** build_dog_pyr( IplImage*** gauss_pyr, int octvs, int intvls ){  IplImage*** dog_pyr;  int i, o;  dog_pyr = calloc( octvs, sizeof( IplImage** ) );  for( i = 0; i < octvs; i++ )    dog_pyr[i] = calloc( intvls + 2, sizeof(IplImage*) );  for( o = 0; o < octvs; o++ )    for( i = 0; i < intvls + 2; i++ )      {	dog_pyr[o][i] = cvCreateImage( cvGetSize(gauss_pyr[o][i]),				       IPL_DEPTH_32F, 1 );	cvSub( gauss_pyr[o][i+1], gauss_pyr[o][i], dog_pyr[o][i], NULL );      }  return dog_pyr;}/*  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;}/*  Determines whether a pixel is a scale-space extremum by comparing it to it's  3x3x3 pixel neighborhood.  @param dog_pyr DoG scale space pyramid  @param octv pixel's scale space octave  @param intvl pixel's within-octave interval  @param r pixel's image row  @param c pixel's image col  @return Returns 1 if the specified pixel is an extremum (max or min) among    it's 3x3x3 pixel neighborhood.*/int is_extremum( IplImage*** dog_pyr, int octv, int intvl, int r, int c ){  double val = pixval32f( dog_pyr[octv][intvl], r, c );  int i, j, k;  /* check for maximum */  if( val > 0 )    {      for( i = -1; i <= 1; i++ )	for( j = -1; j <= 1; j++ )	  for( k = -1; k <= 1; k++ )	    if( val < pixval32f( dog_pyr[octv][intvl+i], r + j, c + k ) )	      return 0;    }  /* check for minimum */  else    {      for( i = -1; i <= 1; i++ )	for( j = -1; j <= 1; j++ )	  for( k = -1; k <= 1; k++ )	    if( val > pixval32f( dog_pyr[octv][intvl+i], r + j, c + k ) )	      return 0;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -