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

📄 sift.c

📁 Rob Hess Linux下的SIFT提取源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  @param img image  @param r pixel row  @param c pixel col  @param mag output as gradient magnitude at pixel (r,c)  @param ori output as gradient orientation at pixel (r,c)  @return Returns 1 if the specified pixel is a valid one and sets mag and    ori accordingly; otherwise returns 0*/int calc_grad_mag_ori( IplImage* img, int r, int c, double* mag, double* ori ){  double dx, dy;  if( r > 0  &&  r < img->height - 1  &&  c > 0  &&  c < img->width - 1 )    {      dx = pixval32f( img, r, c+1 ) - pixval32f( img, r, c-1 );      dy = pixval32f( img, r-1, c ) - pixval32f( img, r+1, c );      *mag = sqrt( dx*dx + dy*dy );      *ori = atan2( dy, dx );      return 1;    }  else    return 0;}/*  Gaussian smooths an orientation histogram.  @param hist an orientation histogram  @param n number of bins*/void smooth_ori_hist( double* hist, int n ){  double prev, tmp, h0 = hist[0];  int i;  prev = hist[n-1];  for( i = 0; i < n; i++ )    {      tmp = hist[i];      hist[i] = 0.25 * prev + 0.5 * hist[i] + 	0.25 * ( ( i+1 == n )? h0 : hist[i+1] );      prev = tmp;    }}/*  Finds the magnitude of the dominant orientation in a histogram  @param hist an orientation histogram  @param n number of bins  @return Returns the value of the largest bin in hist*/double dominant_ori( double* hist, int n ){  double omax;  int maxbin, i;  omax = hist[0];  maxbin = 0;  for( i = 1; i < n; i++ )    if( hist[i] > omax )      {	omax = hist[i];	maxbin = i;      }  return omax;}/*  Interpolates a histogram peak from left, center, and right values*/#define interp_hist_peak( l, c, r ) ( 0.5 * ((l)-(r)) / ((l) - 2.0*(c) + (r)) )/*  Adds features to an array for every orientation in a histogram greater than  a specified threshold.  @param features new features are added to the end of this array  @param hist orientation histogram  @param n number of bins in hist  @param mag_thr new features are added for entries in hist greater than this  @param feat new features are clones of this with different orientations*/void add_good_ori_features( CvSeq* features, double* hist, int n,			    double mag_thr, struct feature* feat ){  struct feature* new_feat;  double bin, PI2 = CV_PI * 2.0;  int l, r, i;  for( i = 0; i < n; i++ )    {      l = ( i == 0 )? n - 1 : i-1;      r = ( i + 1 ) % n;            if( hist[i] > hist[l]  &&  hist[i] > hist[r]  &&  hist[i] >= mag_thr )	{	  bin = i + interp_hist_peak( hist[l], hist[i], hist[r] );	  bin = ( bin < 0 )? n + bin : ( bin >= n )? bin - n : bin;	  new_feat = clone_feature( feat );	  new_feat->ori = ( ( PI2 * bin ) / n ) - CV_PI;	  cvSeqPush( features, new_feat );	  free( new_feat );	}    }}/*  Makes a deep copy of a feature  @param feat feature to be cloned  @return Returns a deep copy of feat*/struct feature* clone_feature( struct feature* feat ){  struct feature* new_feat;  struct detection_data* ddata;  new_feat = new_feature();  ddata = feat_detection_data( new_feat );  memcpy( new_feat, feat, sizeof( struct feature ) );  memcpy( ddata, feat_detection_data(feat), sizeof( struct detection_data ) );  new_feat->feature_data = ddata;  return new_feat;}/*  Computes feature descriptors for features in an array.  Based on Section 6  of Lowe's paper.  @param features array of features  @param gauss_pyr Gaussian scale space pyramid  @param d width of 2D array of orientation histograms  @param n number of bins per orientation histogram*/void compute_descriptors( CvSeq* features, IplImage*** gauss_pyr, int d, int n){  struct feature* feat;  struct detection_data* ddata;  double*** hist;  int i, k = features->total;  for( i = 0; i < k; i++ )    {      feat = CV_GET_SEQ_ELEM( struct feature, features, i );      ddata = feat_detection_data( feat );      hist = descr_hist( gauss_pyr[ddata->octv][ddata->intvl], ddata->r,			 ddata->c, feat->ori, ddata->scl_octv, d, n );      hist_to_descr( hist, d, n, feat );      release_descr_hist( &hist, d );    }}/*  Computes the 2D array of orientation histograms that form the feature  descriptor.  Based on Section 6.1 of Lowe's paper.  @param img image used in descriptor computation  @param r row coord of center of orientation histogram array  @param c column coord of center of orientation histogram array  @param ori canonical orientation of feature whose descr is being computed  @param scl scale relative to img of feature whose descr is being computed  @param d width of 2d array of orientation histograms  @param n bins per orientation histogram  @return Returns a d x d array of n-bin orientation histograms.*/double*** descr_hist( IplImage* img, int r, int c, double ori,		      double scl, int d, int n ){  double*** hist;  double cos_t, sin_t, hist_width, exp_denom, r_rot, c_rot, grad_mag,    grad_ori, w, rbin, cbin, obin, bins_per_rad, PI2 = 2.0 * CV_PI;  int radius, i, j;  hist = calloc( d, sizeof( double** ) );  for( i = 0; i < d; i++ )    {      hist[i] = calloc( d, sizeof( double* ) );      for( j = 0; j < d; j++ )	hist[i][j] = calloc( n, sizeof( double ) );    }    cos_t = cos( ori );  sin_t = sin( ori );  bins_per_rad = n / PI2;  exp_denom = d * d * 0.5;  hist_width = SIFT_DESCR_SCL_FCTR * scl;  radius = hist_width * sqrt(2) * ( d + 1.0 ) * 0.5 + 0.5;  for( i = -radius; i <= radius; i++ )    for( j = -radius; j <= radius; j++ )      {	/*	  Calculate sample's histogram array coords rotated relative to ori.	  Subtract 0.5 so samples that fall e.g. in the center of row 1 (i.e.	  r_rot = 1.5) have full weight placed in row 1 after interpolation.	*/	c_rot = ( j * cos_t - i * sin_t ) / hist_width;	r_rot = ( j * sin_t + i * cos_t ) / hist_width;	rbin = r_rot + d / 2 - 0.5;	cbin = c_rot + d / 2 - 0.5;		if( rbin > -1.0  &&  rbin < d  &&  cbin > -1.0  &&  cbin < d )	  if( calc_grad_mag_ori( img, r + i, c + j, &grad_mag, &grad_ori ))	    {	      grad_ori -= ori;	      while( grad_ori < 0.0 )		grad_ori += PI2;	      while( grad_ori >= PI2 )		grad_ori -= PI2;	      	      obin = grad_ori * bins_per_rad;	      w = exp( -(c_rot * c_rot + r_rot * r_rot) / exp_denom );	      interp_hist_entry( hist, rbin, cbin, obin, grad_mag * w, d, n );	    }      }  return hist;}/*  Interpolates an entry into the array of orientation histograms that form  the feature descriptor.  @param hist 2D array of orientation histograms  @param rbin sub-bin row coordinate of entry  @param cbin sub-bin column coordinate of entry  @param obin sub-bin orientation coordinate of entry  @param mag size of entry  @param d width of 2D array of orientation histograms  @param n number of bins per orientation histogram*/void interp_hist_entry( double*** hist, double rbin, double cbin,			double obin, double mag, int d, int n ){  double d_r, d_c, d_o, v_r, v_c, v_o;  double** row, * h;  int r0, c0, o0, rb, cb, ob, r, c, o;  r0 = cvFloor( rbin );  c0 = cvFloor( cbin );  o0 = cvFloor( obin );  d_r = rbin - r0;  d_c = cbin - c0;  d_o = obin - o0;  /*    The entry is distributed into up to 8 bins.  Each entry into a bin    is multiplied by a weight of 1 - d for each dimension, where d is the    distance from the center value of the bin measured in bin units.  */  for( r = 0; r <= 1; r++ )    {      rb = r0 + r;      if( rb >= 0  &&  rb < d )	{	  v_r = mag * ( ( r == 0 )? 1.0 - d_r : d_r );	  row = hist[rb];	  for( c = 0; c <= 1; c++ )	    {	      cb = c0 + c;	      if( cb >= 0  &&  cb < d )		{		  v_c = v_r * ( ( c == 0 )? 1.0 - d_c : d_c );		  h = row[cb];		  for( o = 0; o <= 1; o++ )		    {		      ob = ( o0 + o ) % n;		      v_o = v_c * ( ( o == 0 )? 1.0 - d_o : d_o );		      h[ob] += v_o;		    }		}	    }	}    }}/*  Converts the 2D array of orientation histograms into a feature's descriptor  vector.    @param hist 2D array of orientation histograms  @param d width of hist  @param n bins per histogram  @param feat feature into which to store descriptor*/void hist_to_descr( double*** hist, int d, int n, struct feature* feat ){  int int_val, i, r, c, o, k = 0;  for( r = 0; r < d; r++ )    for( c = 0; c < d; c++ )      for( o = 0; o < n; o++ )	feat->descr[k++] = hist[r][c][o];  feat->d = k;  normalize_descr( feat );  for( i = 0; i < k; i++ )    if( feat->descr[i] > SIFT_DESCR_MAG_THR )      feat->descr[i] = SIFT_DESCR_MAG_THR;  normalize_descr( feat );  /* convert floating-point descriptor to integer valued descriptor */  for( i = 0; i < k; i++ )    {      int_val = SIFT_INT_DESCR_FCTR * feat->descr[i];      feat->descr[i] = MIN( 255, int_val );    }}/*  Normalizes a feature's descriptor vector to unitl length  @param feat feature*/void normalize_descr( struct feature* feat ){  double cur, len_inv, len_sq = 0.0;  int i, d = feat->d;  for( i = 0; i < d; i++ )    {      cur = feat->descr[i];      len_sq += cur*cur;    }  len_inv = 1.0 / sqrt( len_sq );  for( i = 0; i < d; i++ )    feat->descr[i] *= len_inv;}/*  Compares features for a decreasing-scale ordering.  Intended for use with  CvSeqSort  @param feat1 first feature  @param feat2 second feature  @param param unused  @return Returns 1 if feat1's scale is greater than feat2's, -1 if vice versa,    and 0 if their scales are equal*/int feature_cmp( void* feat1, void* feat2, void* param ){  struct feature* f1 = (struct feature*) feat1;  struct feature* f2 = (struct feature*) feat2;  if( f1->scl < f2->scl )    return 1;  if( f1->scl > f2->scl )    return -1;  return 0;}/*  De-allocates memory held by a descriptor histogram  @param hist pointer to a 2D array of orientation histograms  @param d width of hist*/void release_descr_hist( double**** hist, int d ){  int i, j;  for( i = 0; i < d; i++)    {      for( j = 0; j < d; j++ )	free( (*hist)[i][j] );      free( (*hist)[i] );    }  free( *hist );  *hist = NULL;}/*  De-allocates memory held by a scale space pyramid  @param pyr scale space pyramid  @param octvs number of octaves of scale space  @param n number of images per octave*/void release_pyr( IplImage**** pyr, int octvs, int n ){  int i, j;  for( i = 0; i < octvs; i++ )    {      for( j = 0; j < n; j++ )	cvReleaseImage( &(*pyr)[i][j] );      free( (*pyr)[i] );    }  free( *pyr );  *pyr = NULL;}

⌨️ 快捷键说明

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