sift.c
上传用户:lwxipeng
上传日期:2022-05-16
资源大小:15982k
文件大小:35k
源码类别:

视频捕捉/采集

开发平台:

Visual C++

  1. /*
  2. Functions for detecting SIFT image features.
  3. For more information, refer to:
  4. Lowe, D.  Distinctive image features from scale-invariant keypoints.
  5. <EM>International Journal of Computer Vision, 60</EM>, 2 (2004),
  6. pp.91--110.
  7. Copyright (C) 2006  Rob Hess <hess@eecs.oregonstate.edu>
  8. Note: The SIFT algorithm is patented in the United States and cannot be
  9. used in commercial products without a license from the University of
  10. British Columbia.  For more information, refer to the file LICENSE.ubc
  11. that accompanied this distribution.
  12. @version 1.1.1-20070330
  13. */
  14. #include "sift.h"
  15. #include "imgfeatures.h"
  16. #include "utils.h"
  17. #include <cxcore.h>
  18. #include <cv.h>
  19. /************************* Local Function Prototypes *************************/
  20. IplImage* create_init_img( IplImage*, int, double );
  21. IplImage* convert_to_gray32( IplImage* );
  22. IplImage*** build_gauss_pyr( IplImage*, int, int, double );
  23. IplImage* downsample( IplImage* );
  24. IplImage*** build_dog_pyr( IplImage***, int, int );
  25. CvSeq* scale_space_extrema( IplImage***, int, int, double, int, CvMemStorage*);
  26. int is_extremum( IplImage***, int, int, int, int );
  27. struct feature* interp_extremum( IplImage***, int, int, int, int, int, double);
  28. void interp_step( IplImage***, int, int, int, int, double*, double*, double* );
  29. CvMat* deriv_3D( IplImage***, int, int, int, int );
  30. CvMat* hessian_3D( IplImage***, int, int, int, int );
  31. double interp_contr( IplImage***, int, int, int, int, double, double, double );
  32. struct feature* new_feature( void );
  33. int is_too_edge_like( IplImage*, int, int, int );
  34. void calc_feature_scales( CvSeq*, double, int );
  35. void adjust_for_img_dbl( CvSeq* );
  36. void calc_feature_oris( CvSeq*, IplImage*** );
  37. double* ori_hist( IplImage*, int, int, int, int, double );
  38. int calc_grad_mag_ori( IplImage*, int, int, double*, double* );
  39. void smooth_ori_hist( double*, int );
  40. double dominant_ori( double*, int );
  41. void add_good_ori_features( CvSeq*, double*, int, double, struct feature* );
  42. struct feature* clone_feature( struct feature* );
  43. void compute_descriptors( CvSeq*, IplImage***, int, int );
  44. double*** descr_hist( IplImage*, int, int, double, double, int, int );
  45. void interp_hist_entry( double***, double, double, double, double, int, int);
  46. void hist_to_descr( double***, int, int, struct feature* );
  47. void normalize_descr( struct feature* );
  48. int feature_cmp( void*, void*, void* );
  49. void release_descr_hist( double****, int );
  50. void release_pyr( IplImage****, int, int );
  51. /*********************** Functions prototyped in sift.h **********************/
  52. /**
  53. Finds SIFT features in an image using default parameter values.  All
  54. detected features are stored in the array pointed to by a feat.
  55. @param img the image in which to detect features
  56. @param feat a pointer to an array in which to store detected features
  57. @return Returns the number of features stored in a feat or -1 on failure
  58. @see _sift_features()
  59. */
  60. int sift_features( IplImage* img, struct feature** feat )
  61. {
  62. return _sift_features( img, feat, SIFT_INTVLS, SIFT_SIGMA, SIFT_CONTR_THR,
  63. SIFT_CURV_THR, SIFT_IMG_DBL, SIFT_DESCR_WIDTH,
  64. SIFT_DESCR_HIST_BINS );
  65. }
  66. /**
  67. Finds SIFT features in an image using user-specified parameter values.  All
  68. detected features are stored in the array pointed to by a feat.
  69. @param img the image in which to detect features
  70. @param fea a pointer to an array in which to store detected features
  71. @param intvls the number of intervals sampled per octave of scale space
  72. @param sigma the amount of Gaussian smoothing applied to each image level
  73. before building the scale space representation for an octave
  74. @param cont_thr a threshold on the value of the scale space function
  75. f$left|D(hat{x})right|f$, where f$hat{x}f$ is a vector specifying
  76. feature location and scale, used to reject unstable features;  assumes
  77. pixel values in the range [0, 1]
  78. @param curv_thr threshold on a feature's ratio of principle curvatures
  79. used to reject features that are too edge-like
  80. @param img_dbl should be 1 if image doubling prior to scale space
  81. construction is desired or 0 if not
  82. @param descr_width the width, f$nf$, of the f$n times nf$ array of
  83. orientation histograms used to compute a feature's descriptor
  84. @param descr_hist_bins the number of orientations in each of the
  85. histograms in the array used to compute a feature's descriptor
  86. @return Returns the number of keypoints stored in a feat or -1 on failure
  87. @see sift_keypoints()
  88. */
  89. int _sift_features( IplImage* img, struct feature** feat, int intvls,
  90.    double sigma, double contr_thr, int curv_thr,
  91.    int img_dbl, int descr_width, int descr_hist_bins )
  92. {
  93. IplImage* init_img;
  94. IplImage*** gauss_pyr, *** dog_pyr;
  95. CvMemStorage* storage;
  96. CvSeq* features;
  97. int octvs, i, n = 0;
  98. /* check arguments */
  99. if( ! img )
  100. fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );
  101. if( ! feat )
  102. fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );
  103. /* build scale space pyramid; smallest dimension of top level is ~4 pixels */
  104. init_img = create_init_img( img, img_dbl, sigma );
  105. octvs = log( MIN( init_img->width, init_img->height ) ) / log(2) - 2;
  106. gauss_pyr = build_gauss_pyr( init_img, octvs, intvls, sigma );
  107. dog_pyr = build_dog_pyr( gauss_pyr, octvs, intvls );
  108. storage = cvCreateMemStorage( 0 );
  109. features = scale_space_extrema( dog_pyr, octvs, intvls, contr_thr,
  110. curv_thr, storage );
  111. calc_feature_scales( features, sigma, intvls );
  112. if( img_dbl )
  113. adjust_for_img_dbl( features );
  114. calc_feature_oris( features, gauss_pyr );
  115. compute_descriptors( features, gauss_pyr, descr_width, descr_hist_bins );
  116. /* sort features by decreasing scale and move from CvSeq to array */
  117. cvSeqSort( features, (CvCmpFunc)feature_cmp, NULL );
  118. n = features->total;
  119. *feat = calloc( n, sizeof(struct feature) );
  120. *feat = cvCvtSeqToArray( features, *feat, CV_WHOLE_SEQ );
  121. for( i = 0; i < n; i++ )
  122. {
  123. free( (*feat)[i].feature_data );
  124. (*feat)[i].feature_data = NULL;
  125. }
  126. cvReleaseMemStorage( &storage );
  127. cvReleaseImage( &init_img );
  128. release_pyr( &gauss_pyr, octvs, intvls + 3 );
  129. release_pyr( &dog_pyr, octvs, intvls + 2 );
  130. return n;
  131. }
  132. /************************ Functions prototyped here **************************/
  133. /*
  134. Converts an image to 8-bit grayscale and Gaussian-smooths it.  The image is
  135. optionally doubled in size prior to smoothing.
  136. @param img input image
  137. @param img_dbl if true, image is doubled in size prior to smoothing
  138. @param sigma total std of Gaussian smoothing
  139. */
  140. IplImage* create_init_img( IplImage* img, int img_dbl, double sigma )
  141. {
  142. IplImage* gray, * dbl;
  143. float sig_diff;
  144. gray = convert_to_gray32( img );
  145. if( img_dbl )
  146. {
  147. sig_diff = sqrt( sigma * sigma - SIFT_INIT_SIGMA * SIFT_INIT_SIGMA * 4 );
  148. dbl = cvCreateImage( cvSize( img->width*2, img->height*2 ),
  149. IPL_DEPTH_32F, 1 );
  150. cvResize( gray, dbl, CV_INTER_CUBIC );
  151. cvSmooth( dbl, dbl, CV_GAUSSIAN, 0, 0, sig_diff, sig_diff );
  152. cvReleaseImage( &gray );
  153. return dbl;
  154. }
  155. else
  156. {
  157. sig_diff = sqrt( sigma * sigma - SIFT_INIT_SIGMA * SIFT_INIT_SIGMA );
  158. cvSmooth( gray, gray, CV_GAUSSIAN, 0, 0, sig_diff, sig_diff );
  159. return gray;
  160. }
  161. }
  162. /*
  163. Converts an image to 32-bit grayscale
  164. @param img a 3-channel 8-bit color (BGR) or 8-bit gray image
  165. @return Returns a 32-bit grayscale image
  166. */
  167. IplImage* convert_to_gray32( IplImage* img )
  168. {
  169. IplImage* gray8, * gray32;
  170. int r, c;
  171. gray8 = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
  172. gray32 = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );
  173. if( img->nChannels == 1 )
  174. gray8 = cvClone( img );
  175. else
  176. cvCvtColor( img, gray8, CV_RGB2GRAY );
  177. cvConvertScale( gray8, gray32, 1.0 / 255.0, 0 );
  178. cvReleaseImage( &gray8 );
  179. return gray32;
  180. }
  181. /*
  182. Builds Gaussian scale space pyramid from an image
  183. @param base base image of the pyramid
  184. @param octvs number of octaves of scale space
  185. @param intvls number of intervals per octave
  186. @param sigma amount of Gaussian smoothing per octave
  187. @return Returns a Gaussian scale space pyramid as an octvs x (intvls + 3) array
  188. */
  189. IplImage*** build_gauss_pyr( IplImage* base, int octvs,
  190. int intvls, double sigma )
  191. {
  192. IplImage*** gauss_pyr;
  193. double* sig = calloc( intvls + 3, sizeof(double));
  194. double sig_total, sig_prev, k;
  195. int i, o;
  196. gauss_pyr = calloc( octvs, sizeof( IplImage** ) );
  197. for( i = 0; i < octvs; i++ )
  198. gauss_pyr[i] = calloc( intvls + 3, sizeof( IplImage* ) );
  199. /*
  200. precompute Gaussian sigmas using the following formula:
  201. sigma_{total}^2 = sigma_{i}^2 + sigma_{i-1}^2
  202. */
  203. sig[0] = sigma;
  204. k = pow( 2.0, 1.0 / intvls );
  205. for( i = 1; i < intvls + 3; i++ )
  206. {
  207. sig_prev = pow( k, i - 1 ) * sigma;
  208. sig_total = sig_prev * k;
  209. sig[i] = sqrt( sig_total * sig_total - sig_prev * sig_prev );
  210. }
  211. for( o = 0; o < octvs; o++ )
  212. for( i = 0; i < intvls + 3; i++ )
  213. {
  214. if( o == 0  &&  i == 0 )
  215. gauss_pyr[o][i] = cvCloneImage(base);
  216. /* base of new octvave is halved image from end of previous octave */
  217. else if( i == 0 )
  218. gauss_pyr[o][i] = downsample( gauss_pyr[o-1][intvls] );
  219. /* blur the current octave's last image to create the next one */
  220. else
  221. {
  222. gauss_pyr[o][i] = cvCreateImage( cvGetSize(gauss_pyr[o][i-1]),
  223. IPL_DEPTH_32F, 1 );
  224. cvSmooth( gauss_pyr[o][i-1], gauss_pyr[o][i],
  225. CV_GAUSSIAN, 0, 0, sig[i], sig[i] );
  226. }
  227. }
  228. free( sig );
  229. return gauss_pyr;
  230. }
  231. /*
  232. Downsamples an image to a quarter of its size (half in each dimension)
  233. using nearest-neighbor interpolation
  234. @param img an image
  235. @return Returns an image whose dimensions are half those of img
  236. */
  237. IplImage* downsample( IplImage* img )
  238. {
  239. IplImage* smaller = cvCreateImage( cvSize(img->width / 2, img->height / 2),
  240. img->depth, img->nChannels );
  241. cvResize( img, smaller, CV_INTER_NN );
  242. return smaller;
  243. }
  244. /*
  245. Builds a difference of Gaussians scale space pyramid by subtracting adjacent
  246. intervals of a Gaussian pyramid
  247. @param gauss_pyr Gaussian scale-space pyramid
  248. @param octvs number of octaves of scale space
  249. @param intvls number of intervals per octave
  250. @return Returns a difference of Gaussians scale space pyramid as an
  251. octvs x (intvls + 2) array
  252. */
  253. IplImage*** build_dog_pyr( IplImage*** gauss_pyr, int octvs, int intvls )
  254. {
  255. IplImage*** dog_pyr;
  256. int i, o;
  257. dog_pyr = calloc( octvs, sizeof( IplImage** ) );
  258. for( i = 0; i < octvs; i++ )
  259. dog_pyr[i] = calloc( intvls + 2, sizeof(IplImage*) );
  260. for( o = 0; o < octvs; o++ )
  261. for( i = 0; i < intvls + 2; i++ )
  262. {
  263. dog_pyr[o][i] = cvCreateImage( cvGetSize(gauss_pyr[o][i]),
  264. IPL_DEPTH_32F, 1 );
  265. cvSub( gauss_pyr[o][i+1], gauss_pyr[o][i], dog_pyr[o][i], NULL );
  266. }
  267. return dog_pyr;
  268. }
  269. /*
  270. Detects features at extrema in DoG scale space.  Bad features are discarded
  271. based on contrast and ratio of principal curvatures.
  272. @param dog_pyr DoG scale space pyramid
  273. @param octvs octaves of scale space represented by dog_pyr
  274. @param intvls intervals per octave
  275. @param contr_thr low threshold on feature contrast
  276. @param curv_thr high threshold on feature ratio of principal curvatures
  277. @param storage memory storage in which to store detected features
  278. @return Returns an array of detected features whose scales, orientations,
  279. and descriptors are yet to be determined.
  280. */
  281. CvSeq* scale_space_extrema( IplImage*** dog_pyr, int octvs, int intvls,
  282.    double contr_thr, int curv_thr,
  283.    CvMemStorage* storage )
  284. {
  285. CvSeq* features;
  286. double prelim_contr_thr = 0.5 * contr_thr / intvls;
  287. struct feature* feat;
  288. struct detection_data* ddata;
  289. int o, i, r, c, w, h;
  290. features = cvCreateSeq( 0, sizeof(CvSeq), sizeof(struct feature), storage );
  291. for( o = 0; o < octvs; o++ )
  292. for( i = 1; i <= intvls; i++ )
  293. for(r = SIFT_IMG_BORDER; r < dog_pyr[o][0]->height-SIFT_IMG_BORDER; r++)
  294. for(c = SIFT_IMG_BORDER; c < dog_pyr[o][0]->width-SIFT_IMG_BORDER; c++)
  295. /* perform preliminary check on contrast */
  296. if( ABS( pixval32f( dog_pyr[o][i], r, c ) ) > prelim_contr_thr )
  297. if( is_extremum( dog_pyr, o, i, r, c ) )
  298. {
  299. feat = interp_extremum(dog_pyr, o, i, r, c, intvls, contr_thr);
  300. if( feat )
  301. {
  302. ddata = feat_detection_data( feat );
  303. if( ! is_too_edge_like( dog_pyr[ddata->octv][ddata->intvl],
  304. ddata->r, ddata->c, curv_thr ) )
  305. {
  306. cvSeqPush( features, feat );
  307. }
  308. else
  309. free( ddata );
  310. free( feat );
  311. }
  312. }
  313. return features;
  314. }
  315. /*
  316. Determines whether a pixel is a scale-space extremum by comparing it to it's
  317. 3x3x3 pixel neighborhood.
  318. @param dog_pyr DoG scale space pyramid
  319. @param octv pixel's scale space octave
  320. @param intvl pixel's within-octave interval
  321. @param r pixel's image row
  322. @param c pixel's image col
  323. @return Returns 1 if the specified pixel is an extremum (max or min) among
  324. it's 3x3x3 pixel neighborhood.
  325. */
  326. int is_extremum( IplImage*** dog_pyr, int octv, int intvl, int r, int c )
  327. {
  328. float val = pixval32f( dog_pyr[octv][intvl], r, c );
  329. int i, j, k;
  330. /* check for maximum */
  331. if( val > 0 )
  332. {
  333. for( i = -1; i <= 1; i++ )
  334. for( j = -1; j <= 1; j++ )
  335. for( k = -1; k <= 1; k++ )
  336. if( val < pixval32f( dog_pyr[octv][intvl+i], r + j, c + k ) )
  337. return 0;
  338. }
  339. /* check for minimum */
  340. else
  341. {
  342. for( i = -1; i <= 1; i++ )
  343. for( j = -1; j <= 1; j++ )
  344. for( k = -1; k <= 1; k++ )
  345. if( val > pixval32f( dog_pyr[octv][intvl+i], r + j, c + k ) )
  346. return 0;
  347. }
  348. return 1;
  349. }
  350. /*
  351. Interpolates a scale-space extremum's location and scale to subpixel
  352. accuracy to form an image feature.  Rejects features with low contrast.
  353. Based on Section 4 of Lowe's paper.  
  354. @param dog_pyr DoG scale space pyramid
  355. @param octv feature's octave of scale space
  356. @param intvl feature's within-octave interval
  357. @param r feature's image row
  358. @param c feature's image column
  359. @param intvls total intervals per octave
  360. @param contr_thr threshold on feature contrast
  361. @return Returns the feature resulting from interpolation of the given
  362. parameters or NULL if the given location could not be interpolated or
  363. if contrast at the interpolated loation was too low.  If a feature is
  364. returned, its scale, orientation, and descriptor are yet to be determined.
  365. */
  366. struct feature* interp_extremum( IplImage*** dog_pyr, int octv, int intvl,
  367. int r, int c, int intvls, double contr_thr )
  368. {
  369. struct feature* feat;
  370. struct detection_data* ddata;
  371. double xi, xr, xc, contr;
  372. int i = 0;
  373. while( i < SIFT_MAX_INTERP_STEPS )
  374. {
  375. interp_step( dog_pyr, octv, intvl, r, c, &xi, &xr, &xc );
  376. if( ABS( xi ) < 0.5  &&  ABS( xr ) < 0.5  &&  ABS( xc ) < 0.5 )
  377. break;
  378. c += cvRound( xc );
  379. r += cvRound( xr );
  380. intvl += cvRound( xi );
  381. if( intvl < 1  ||
  382. intvl > intvls  ||
  383. c < SIFT_IMG_BORDER  ||
  384. r < SIFT_IMG_BORDER  ||
  385. c >= dog_pyr[octv][0]->width - SIFT_IMG_BORDER  ||
  386. r >= dog_pyr[octv][0]->height - SIFT_IMG_BORDER )
  387. {
  388. return NULL;
  389. }
  390. i++;
  391. }
  392. /* ensure convergence of interpolation */
  393. if( i >= SIFT_MAX_INTERP_STEPS )
  394. return NULL;
  395. contr = interp_contr( dog_pyr, octv, intvl, r, c, xi, xr, xc );
  396. if( ABS( contr ) < contr_thr / intvls )
  397. return NULL;
  398. feat = new_feature();
  399. ddata = feat_detection_data( feat );
  400. feat->img_pt.x = feat->x = ( c + xc ) * pow( 2.0, octv );
  401. feat->img_pt.y = feat->y = ( r + xr ) * pow( 2.0, octv );
  402. ddata->r = r;
  403. ddata->c = c;
  404. ddata->octv = octv;
  405. ddata->intvl = intvl;
  406. ddata->subintvl = xi;
  407. return feat;
  408. }
  409. /*
  410. Performs one step of extremum interpolation.  Based on Eqn. (3) in Lowe's
  411. paper.
  412. @param dog_pyr difference of Gaussians scale space pyramid
  413. @param octv octave of scale space
  414. @param intvl interval being interpolated
  415. @param r row being interpolated
  416. @param c column being interpolated
  417. @param xi output as interpolated subpixel increment to interval
  418. @param xr output as interpolated subpixel increment to row
  419. @param xc output as interpolated subpixel increment to col
  420. */
  421. void interp_step( IplImage*** dog_pyr, int octv, int intvl, int r, int c,
  422.  double* xi, double* xr, double* xc )
  423. {
  424. CvMat* dD, * H, * H_inv, X;
  425. double x[3] = { 0 };
  426. dD = deriv_3D( dog_pyr, octv, intvl, r, c );
  427. H = hessian_3D( dog_pyr, octv, intvl, r, c );
  428. H_inv = cvCreateMat( 3, 3, CV_64FC1 );
  429. cvInvert( H, H_inv, CV_SVD );
  430. cvInitMatHeader( &X, 3, 1, CV_64FC1, x, CV_AUTOSTEP );
  431. cvGEMM( H_inv, dD, -1, NULL, 0, &X, 0 );
  432. cvReleaseMat( &dD );
  433. cvReleaseMat( &H );
  434. cvReleaseMat( &H_inv );
  435. *xi = x[2];
  436. *xr = x[1];
  437. *xc = x[0];
  438. }
  439. /*
  440. Computes the partial derivatives in x, y, and scale of a pixel in the DoG
  441. scale space pyramid.
  442. @param dog_pyr DoG scale space pyramid
  443. @param octv pixel's octave in dog_pyr
  444. @param intvl pixel's interval in octv
  445. @param r pixel's image row
  446. @param c pixel's image col
  447. @return Returns the vector of partial derivatives for pixel I
  448. { dI/dx, dI/dy, dI/ds }^T as a CvMat*
  449. */
  450. CvMat* deriv_3D( IplImage*** dog_pyr, int octv, int intvl, int r, int c )
  451. {
  452. CvMat* dI;
  453. double dx, dy, ds;
  454. dx = ( pixval32f( dog_pyr[octv][intvl], r, c+1 ) -
  455. pixval32f( dog_pyr[octv][intvl], r, c-1 ) ) / 2.0;
  456. dy = ( pixval32f( dog_pyr[octv][intvl], r+1, c ) -
  457. pixval32f( dog_pyr[octv][intvl], r-1, c ) ) / 2.0;
  458. ds = ( pixval32f( dog_pyr[octv][intvl+1], r, c ) -
  459. pixval32f( dog_pyr[octv][intvl-1], r, c ) ) / 2.0;
  460. dI = cvCreateMat( 3, 1, CV_64FC1 );
  461. cvmSet( dI, 0, 0, dx );
  462. cvmSet( dI, 1, 0, dy );
  463. cvmSet( dI, 2, 0, ds );
  464. return dI;
  465. }
  466. /*
  467. Computes the 3D Hessian matrix for a pixel in the DoG scale space pyramid.
  468. @param dog_pyr DoG scale space pyramid
  469. @param octv pixel's octave in dog_pyr
  470. @param intvl pixel's interval in octv
  471. @param r pixel's image row
  472. @param c pixel's image col
  473. @return Returns the Hessian matrix (below) for pixel I as a CvMat*
  474. / Ixx  Ixy  Ixs  <BR>
  475. | Ixy  Iyy  Iys | <BR>
  476.  Ixs  Iys  Iss /
  477. */
  478. CvMat* hessian_3D( IplImage*** dog_pyr, int octv, int intvl, int r, int c )
  479. {
  480. CvMat* H;
  481. double v, dxx, dyy, dss, dxy, dxs, dys;
  482. v = pixval32f( dog_pyr[octv][intvl], r, c );
  483. dxx = ( pixval32f( dog_pyr[octv][intvl], r, c+1 ) + 
  484. pixval32f( dog_pyr[octv][intvl], r, c-1 ) - 2 * v );
  485. dyy = ( pixval32f( dog_pyr[octv][intvl], r+1, c ) +
  486. pixval32f( dog_pyr[octv][intvl], r-1, c ) - 2 * v );
  487. dss = ( pixval32f( dog_pyr[octv][intvl+1], r, c ) +
  488. pixval32f( dog_pyr[octv][intvl-1], r, c ) - 2 * v );
  489. dxy = ( pixval32f( dog_pyr[octv][intvl], r+1, c+1 ) -
  490. pixval32f( dog_pyr[octv][intvl], r+1, c-1 ) -
  491. pixval32f( dog_pyr[octv][intvl], r-1, c+1 ) +
  492. pixval32f( dog_pyr[octv][intvl], r-1, c-1 ) ) / 4.0;
  493. dxs = ( pixval32f( dog_pyr[octv][intvl+1], r, c+1 ) -
  494. pixval32f( dog_pyr[octv][intvl+1], r, c-1 ) -
  495. pixval32f( dog_pyr[octv][intvl-1], r, c+1 ) +
  496. pixval32f( dog_pyr[octv][intvl-1], r, c-1 ) ) / 4.0;
  497. dys = ( pixval32f( dog_pyr[octv][intvl+1], r+1, c ) -
  498. pixval32f( dog_pyr[octv][intvl+1], r-1, c ) -
  499. pixval32f( dog_pyr[octv][intvl-1], r+1, c ) +
  500. pixval32f( dog_pyr[octv][intvl-1], r-1, c ) ) / 4.0;
  501. H = cvCreateMat( 3, 3, CV_64FC1 );
  502. cvmSet( H, 0, 0, dxx );
  503. cvmSet( H, 0, 1, dxy );
  504. cvmSet( H, 0, 2, dxs );
  505. cvmSet( H, 1, 0, dxy );
  506. cvmSet( H, 1, 1, dyy );
  507. cvmSet( H, 1, 2, dys );
  508. cvmSet( H, 2, 0, dxs );
  509. cvmSet( H, 2, 1, dys );
  510. cvmSet( H, 2, 2, dss );
  511. return H;
  512. }
  513. /*
  514. Calculates interpolated pixel contrast.  Based on Eqn. (3) in Lowe's paper.
  515. @param dog_pyr difference of Gaussians scale space pyramid
  516. @param octv octave of scale space
  517. @param intvl within-octave interval
  518. @param r pixel row
  519. @param c pixel column
  520. @param xi interpolated subpixel increment to interval
  521. @param xr interpolated subpixel increment to row
  522. @param xc interpolated subpixel increment to col
  523. @param Returns interpolated contrast.
  524. */
  525. double interp_contr( IplImage*** dog_pyr, int octv, int intvl, int r,
  526. int c, double xi, double xr, double xc )
  527. {
  528. CvMat* dD, X, T;
  529. double t[1], x[3] = { xc, xr, xi };
  530. cvInitMatHeader( &X, 3, 1, CV_64FC1, x, CV_AUTOSTEP );
  531. cvInitMatHeader( &T, 1, 1, CV_64FC1, t, CV_AUTOSTEP );
  532. dD = deriv_3D( dog_pyr, octv, intvl, r, c );
  533. cvGEMM( dD, &X, 1, NULL, 0, &T,  CV_GEMM_A_T );
  534. cvReleaseMat( &dD );
  535. return pixval32f( dog_pyr[octv][intvl], r, c ) + t[0] * 0.5;
  536. }
  537. /*
  538. Allocates and initializes a new feature
  539. @return Returns a pointer to the new feature
  540. */
  541. struct feature* new_feature( void )
  542. {
  543. struct feature* feat;
  544. struct detection_data* ddata;
  545. feat = malloc( sizeof( struct feature ) );
  546. memset( feat, 0, sizeof( struct feature ) );
  547. ddata = malloc( sizeof( struct detection_data ) );
  548. memset( ddata, 0, sizeof( struct detection_data ) );
  549. feat->feature_data = ddata;
  550. feat->type = FEATURE_LOWE;
  551. return feat;
  552. }
  553. /*
  554. Determines whether a feature is too edge like to be stable by computing the
  555. ratio of principal curvatures at that feature.  Based on Section 4.1 of
  556. Lowe's paper.
  557. @param dog_img image from the DoG pyramid in which feature was detected
  558. @param r feature row
  559. @param c feature col
  560. @param curv_thr high threshold on ratio of principal curvatures
  561. @return Returns 0 if the feature at (r,c) in dog_img is sufficiently
  562. corner-like or 1 otherwise.
  563. */
  564. int is_too_edge_like( IplImage* dog_img, int r, int c, int curv_thr )
  565. {
  566. double d, dxx, dyy, dxy, tr, det;
  567. /* principal curvatures are computed using the trace and det of Hessian */
  568. d = pixval32f(dog_img, r, c);
  569. dxx = pixval32f( dog_img, r, c+1 ) + pixval32f( dog_img, r, c-1 ) - 2 * d;
  570. dyy = pixval32f( dog_img, r+1, c ) + pixval32f( dog_img, r-1, c ) - 2 * d;
  571. dxy = ( pixval32f(dog_img, r+1, c+1) - pixval32f(dog_img, r+1, c-1) -
  572. pixval32f(dog_img, r-1, c+1) + pixval32f(dog_img, r-1, c-1) ) / 4.0;
  573. tr = dxx + dyy;
  574. det = dxx * dyy - dxy * dxy;
  575. /* negative determinant -> curvatures have different signs; reject feature */
  576. if( det <= 0 )
  577. return 1;
  578. if( tr * tr / det < ( curv_thr + 1.0 )*( curv_thr + 1.0 ) / curv_thr )
  579. return 0;
  580. return 1;
  581. }
  582. /*
  583. Calculates characteristic scale for each feature in an array.
  584. @param features array of features
  585. @param sigma amount of Gaussian smoothing per octave of scale space
  586. @param intvls intervals per octave of scale space
  587. */
  588. void calc_feature_scales( CvSeq* features, double sigma, int intvls )
  589. {
  590. struct feature* feat;
  591. struct detection_data* ddata;
  592. double intvl;
  593. int i, n;
  594. n = features->total;
  595. for( i = 0; i < n; i++ )
  596. {
  597. feat = CV_GET_SEQ_ELEM( struct feature, features, i );
  598. ddata = feat_detection_data( feat );
  599. intvl = ddata->intvl + ddata->subintvl;
  600. feat->scl = sigma * pow( 2.0, ddata->octv + intvl / intvls );
  601. ddata->scl_octv = sigma * pow( 2.0, intvl / intvls );
  602. }
  603. }
  604. /*
  605. Halves feature coordinates and scale in case the input image was doubled
  606. prior to scale space construction.
  607. @param features array of features
  608. */
  609. void adjust_for_img_dbl( CvSeq* features )
  610. {
  611. struct feature* feat;
  612. int i, n;
  613. n = features->total;
  614. for( i = 0; i < n; i++ )
  615. {
  616. feat = CV_GET_SEQ_ELEM( struct feature, features, i );
  617. feat->x /= 2.0;
  618. feat->y /= 2.0;
  619. feat->scl /= 2.0;
  620. feat->img_pt.x /= 2.0;
  621. feat->img_pt.y /= 2.0;
  622. }
  623. }
  624. /*
  625. Computes a canonical orientation for each image feature in an array.  Based
  626. on Section 5 of Lowe's paper.  This function adds features to the array when
  627. there is more than one dominant orientation at a given feature location.
  628. @param features an array of image features
  629. @param gauss_pyr Gaussian scale space pyramid
  630. */
  631. void calc_feature_oris( CvSeq* features, IplImage*** gauss_pyr )
  632. {
  633. struct feature* feat;
  634. struct detection_data* ddata;
  635. double* hist;
  636. double omax;
  637. int i, j, n = features->total;
  638. for( i = 0; i < n; i++ )
  639. {
  640. feat = malloc( sizeof( struct feature ) );
  641. cvSeqPopFront( features, feat );
  642. ddata = feat_detection_data( feat );
  643. hist = ori_hist( gauss_pyr[ddata->octv][ddata->intvl],
  644. ddata->r, ddata->c, SIFT_ORI_HIST_BINS,
  645. cvRound( SIFT_ORI_RADIUS * ddata->scl_octv ),
  646. SIFT_ORI_SIG_FCTR * ddata->scl_octv );
  647. for( j = 0; j < SIFT_ORI_SMOOTH_PASSES; j++ )
  648. smooth_ori_hist( hist, SIFT_ORI_HIST_BINS );
  649. omax = dominant_ori( hist, SIFT_ORI_HIST_BINS );
  650. add_good_ori_features( features, hist, SIFT_ORI_HIST_BINS,
  651. omax * SIFT_ORI_PEAK_RATIO, feat );
  652. free( ddata );
  653. free( feat );
  654. free( hist );
  655. }
  656. }
  657. /*
  658. Computes a gradient orientation histogram at a specified pixel.
  659. @param img image
  660. @param r pixel row
  661. @param c pixel col
  662. @param n number of histogram bins
  663. @param rad radius of region over which histogram is computed
  664. @param sigma std for Gaussian weighting of histogram entries
  665. @return Returns an n-element array containing an orientation histogram
  666. representing orientations between 0 and 2 PI.
  667. */
  668. double* ori_hist( IplImage* img, int r, int c, int n, int rad, double sigma)
  669. {
  670. double* hist;
  671. double mag, ori, w, exp_denom, PI2 = CV_PI * 2.0;
  672. int bin, i, j;
  673. hist = calloc( n, sizeof( double ) );
  674. exp_denom = 2.0 * sigma * sigma;
  675. for( i = -rad; i <= rad; i++ )
  676. for( j = -rad; j <= rad; j++ )
  677. if( calc_grad_mag_ori( img, r + i, c + j, &mag, &ori ) )
  678. {
  679. w = exp( -( i*i + j*j ) / exp_denom );
  680. bin = cvRound( n * ( ori + CV_PI ) / PI2 );
  681. bin = ( bin < n )? bin : 0;
  682. hist[bin] += w * mag;
  683. }
  684. return hist;
  685. }
  686. /*
  687. Calculates the gradient magnitude and orientation at a given pixel.
  688. @param img image
  689. @param r pixel row
  690. @param c pixel col
  691. @param mag output as gradient magnitude at pixel (r,c)
  692. @param ori output as gradient orientation at pixel (r,c)
  693. @return Returns 1 if the specified pixel is a valid one and sets mag and
  694. ori accordingly; otherwise returns 0
  695. */
  696. int calc_grad_mag_ori( IplImage* img, int r, int c, double* mag, double* ori )
  697. {
  698. double dx, dy;
  699. if( r > 0  &&  r < img->height - 1  &&  c > 0  &&  c < img->width - 1 )
  700. {
  701. dx = pixval32f( img, r, c+1 ) - pixval32f( img, r, c-1 );
  702. dy = pixval32f( img, r-1, c ) - pixval32f( img, r+1, c );
  703. *mag = sqrt( dx*dx + dy*dy );
  704. *ori = atan2( dy, dx );
  705. return 1;
  706. }
  707. else
  708. return 0;
  709. }
  710. /*
  711. Gaussian smooths an orientation histogram.
  712. @param hist an orientation histogram
  713. @param n number of bins
  714. */
  715. void smooth_ori_hist( double* hist, int n )
  716. {
  717. double prev, tmp, h0 = hist[0];
  718. int i;
  719. prev = hist[n-1];
  720. for( i = 0; i < n; i++ )
  721. {
  722. tmp = hist[i];
  723. hist[i] = 0.25 * prev + 0.5 * hist[i] + 
  724. 0.25 * ( ( i+1 == n )? h0 : hist[i+1] );
  725. prev = tmp;
  726. }
  727. }
  728. /*
  729. Finds the magnitude of the dominant orientation in a histogram
  730. @param hist an orientation histogram
  731. @param n number of bins
  732. @return Returns the value of the largest bin in hist
  733. */
  734. double dominant_ori( double* hist, int n )
  735. {
  736. double omax;
  737. int maxbin, i;
  738. omax = hist[0];
  739. maxbin = 0;
  740. for( i = 1; i < n; i++ )
  741. if( hist[i] > omax )
  742. {
  743. omax = hist[i];
  744. maxbin = i;
  745. }
  746. return omax;
  747. }
  748. /*
  749. Interpolates a histogram peak from left, center, and right values
  750. */
  751. #define interp_hist_peak( l, c, r ) ( 0.5 * ((l)-(r)) / ((l) - 2.0*(c) + (r)) )
  752. /*
  753. Adds features to an array for every orientation in a histogram greater than
  754. a specified threshold.
  755. @param features new features are added to the end of this array
  756. @param hist orientation histogram
  757. @param n number of bins in hist
  758. @param mag_thr new features are added for entries in hist greater than this
  759. @param feat new features are clones of this with different orientations
  760. */
  761. void add_good_ori_features( CvSeq* features, double* hist, int n,
  762.    double mag_thr, struct feature* feat )
  763. {
  764. struct feature* new_feat;
  765. double bin, PI2 = CV_PI * 2.0;
  766. int l, r, i;
  767. for( i = 0; i < n; i++ )
  768. {
  769. l = ( i == 0 )? n - 1 : i-1;
  770. r = ( i + 1 ) % n;
  771. if( hist[i] > hist[l]  &&  hist[i] > hist[r]  &&  hist[i] >= mag_thr )
  772. {
  773. bin = i + interp_hist_peak( hist[l], hist[i], hist[r] );
  774. bin = ( bin < 0 )? n + bin : ( bin >= n )? bin - n : bin;
  775. new_feat = clone_feature( feat );
  776. new_feat->ori = ( ( PI2 * bin ) / n ) - CV_PI;
  777. cvSeqPush( features, new_feat );
  778. free( new_feat );
  779. }
  780. }
  781. }
  782. /*
  783. Makes a deep copy of a feature
  784. @param feat feature to be cloned
  785. @return Returns a deep copy of feat
  786. */
  787. struct feature* clone_feature( struct feature* feat )
  788. {
  789. struct feature* new_feat;
  790. struct detection_data* ddata;
  791. new_feat = new_feature();
  792. ddata = feat_detection_data( new_feat );
  793. memcpy( new_feat, feat, sizeof( struct feature ) );
  794. memcpy( ddata, feat_detection_data(feat), sizeof( struct detection_data ) );
  795. new_feat->feature_data = ddata;
  796. return new_feat;
  797. }
  798. /*
  799. Computes feature descriptors for features in an array.  Based on Section 6
  800. of Lowe's paper.
  801. @param features array of features
  802. @param gauss_pyr Gaussian scale space pyramid
  803. @param d width of 2D array of orientation histograms
  804. @param n number of bins per orientation histogram
  805. */
  806. void compute_descriptors( CvSeq* features, IplImage*** gauss_pyr, int d, int n)
  807. {
  808. struct feature* feat;
  809. struct detection_data* ddata;
  810. double*** hist;
  811. int i, k = features->total;
  812. for( i = 0; i < k; i++ )
  813. {
  814. feat = CV_GET_SEQ_ELEM( struct feature, features, i );
  815. ddata = feat_detection_data( feat );
  816. hist = descr_hist( gauss_pyr[ddata->octv][ddata->intvl], ddata->r,
  817. ddata->c, feat->ori, ddata->scl_octv, d, n );
  818. hist_to_descr( hist, d, n, feat );
  819. release_descr_hist( &hist, d );
  820. }
  821. }
  822. /*
  823. Computes the 2D array of orientation histograms that form the feature
  824. descriptor.  Based on Section 6.1 of Lowe's paper.
  825. @param img image used in descriptor computation
  826. @param r row coord of center of orientation histogram array
  827. @param c column coord of center of orientation histogram array
  828. @param ori canonical orientation of feature whose descr is being computed
  829. @param scl scale relative to img of feature whose descr is being computed
  830. @param d width of 2d array of orientation histograms
  831. @param n bins per orientation histogram
  832. @return Returns a d x d array of n-bin orientation histograms.
  833. */
  834. double*** descr_hist( IplImage* img, int r, int c, double ori,
  835.  double scl, int d, int n )
  836. {
  837. double*** hist;
  838. double cos_t, sin_t, hist_width, exp_denom, r_rot, c_rot, grad_mag,
  839. grad_ori, w, rbin, cbin, obin, bins_per_rad, PI2 = 2.0 * CV_PI;
  840. int radius, i, j;
  841. hist = calloc( d, sizeof( double** ) );
  842. for( i = 0; i < d; i++ )
  843. {
  844. hist[i] = calloc( d, sizeof( double* ) );
  845. for( j = 0; j < d; j++ )
  846. hist[i][j] = calloc( n, sizeof( double ) );
  847. }
  848. cos_t = cos( ori );
  849. sin_t = sin( ori );
  850. bins_per_rad = n / PI2;
  851. exp_denom = d * d * 0.5;
  852. hist_width = SIFT_DESCR_SCL_FCTR * scl;
  853. radius = hist_width * sqrt(2) * ( d + 1.0 ) * 0.5 + 0.5;
  854. for( i = -radius; i <= radius; i++ )
  855. for( j = -radius; j <= radius; j++ )
  856. {
  857. /*
  858. Calculate sample's histogram array coords rotated relative to ori.
  859. Subtract 0.5 so samples that fall e.g. in the center of row 1 (i.e.
  860. r_rot = 1.5) have full weight placed in row 1 after interpolation.
  861. */
  862. c_rot = ( j * cos_t - i * sin_t ) / hist_width;
  863. r_rot = ( j * sin_t + i * cos_t ) / hist_width;
  864. rbin = r_rot + d / 2 - 0.5;
  865. cbin = c_rot + d / 2 - 0.5;
  866. if( rbin > -1.0  &&  rbin < d  &&  cbin > -1.0  &&  cbin < d )
  867. if( calc_grad_mag_ori( img, r + i, c + j, &grad_mag, &grad_ori ))
  868. {
  869. grad_ori -= ori;
  870. while( grad_ori < 0.0 )
  871. grad_ori += PI2;
  872. while( grad_ori >= PI2 )
  873. grad_ori -= PI2;
  874. obin = grad_ori * bins_per_rad;
  875. w = exp( -(c_rot * c_rot + r_rot * r_rot) / exp_denom );
  876. interp_hist_entry( hist, rbin, cbin, obin, grad_mag * w, d, n );
  877. }
  878. }
  879. return hist;
  880. }
  881. /*
  882. Interpolates an entry into the array of orientation histograms that form
  883. the feature descriptor.
  884. @param hist 2D array of orientation histograms
  885. @param rbin sub-bin row coordinate of entry
  886. @param cbin sub-bin column coordinate of entry
  887. @param obin sub-bin orientation coordinate of entry
  888. @param mag size of entry
  889. @param d width of 2D array of orientation histograms
  890. @param n number of bins per orientation histogram
  891. */
  892. void interp_hist_entry( double*** hist, double rbin, double cbin,
  893.    double obin, double mag, int d, int n )
  894. {
  895. double d_r, d_c, d_o, v_r, v_c, v_o;
  896. double** row, * h;
  897. int r0, c0, o0, rb, cb, ob, r, c, o;
  898. r0 = cvFloor( rbin );
  899. c0 = cvFloor( cbin );
  900. o0 = cvFloor( obin );
  901. d_r = rbin - r0;
  902. d_c = cbin - c0;
  903. d_o = obin - o0;
  904. /*
  905. The entry is distributed into up to 8 bins.  Each entry into a bin
  906. is multiplied by a weight of 1 - d for each dimension, where d is the
  907. distance from the center value of the bin measured in bin units.
  908. */
  909. for( r = 0; r <= 1; r++ )
  910. {
  911. rb = r0 + r;
  912. if( rb >= 0  &&  rb < d )
  913. {
  914. v_r = mag * ( ( r == 0 )? 1.0 - d_r : d_r );
  915. row = hist[rb];
  916. for( c = 0; c <= 1; c++ )
  917. {
  918. cb = c0 + c;
  919. if( cb >= 0  &&  cb < d )
  920. {
  921. v_c = v_r * ( ( c == 0 )? 1.0 - d_c : d_c );
  922. h = row[cb];
  923. for( o = 0; o <= 1; o++ )
  924. {
  925. ob = ( o0 + o ) % n;
  926. v_o = v_c * ( ( o == 0 )? 1.0 - d_o : d_o );
  927. h[ob] += v_o;
  928. }
  929. }
  930. }
  931. }
  932. }
  933. }
  934. /*
  935. Converts the 2D array of orientation histograms into a feature's descriptor
  936. vector.
  937. @param hist 2D array of orientation histograms
  938. @param d width of hist
  939. @param n bins per histogram
  940. @param feat feature into which to store descriptor
  941. */
  942. void hist_to_descr( double*** hist, int d, int n, struct feature* feat )
  943. {
  944. int int_val, i, r, c, o, k = 0;
  945. for( r = 0; r < d; r++ )
  946. for( c = 0; c < d; c++ )
  947. for( o = 0; o < n; o++ )
  948. feat->descr[k++] = hist[r][c][o];
  949. feat->d = k;
  950. normalize_descr( feat );
  951. for( i = 0; i < k; i++ )
  952. if( feat->descr[i] > SIFT_DESCR_MAG_THR )
  953. feat->descr[i] = SIFT_DESCR_MAG_THR;
  954. normalize_descr( feat );
  955. /* convert floating-point descriptor to integer valued descriptor */
  956. for( i = 0; i < k; i++ )
  957. {
  958. int_val = SIFT_INT_DESCR_FCTR * feat->descr[i];
  959. feat->descr[i] = MIN( 255, int_val );
  960. }
  961. }
  962. /*
  963. Normalizes a feature's descriptor vector to unitl length
  964. @param feat feature
  965. */
  966. void normalize_descr( struct feature* feat )
  967. {
  968. double cur, len_inv, len_sq = 0.0;
  969. int i, d = feat->d;
  970. for( i = 0; i < d; i++ )
  971. {
  972. cur = feat->descr[i];
  973. len_sq += cur*cur;
  974. }
  975. len_inv = 1.0 / sqrt( len_sq );
  976. for( i = 0; i < d; i++ )
  977. feat->descr[i] *= len_inv;
  978. }
  979. /*
  980. Compares features for a decreasing-scale ordering.  Intended for use with
  981. CvSeqSort
  982. @param feat1 first feature
  983. @param feat2 second feature
  984. @param param unused
  985. @return Returns 1 if feat1's scale is greater than feat2's, -1 if vice versa,
  986. and 0 if their scales are equal
  987. */
  988. int feature_cmp( void* feat1, void* feat2, void* param )
  989. {
  990. struct feature* f1 = (struct feature*) feat1;
  991. struct feature* f2 = (struct feature*) feat2;
  992. if( f1->scl < f2->scl )
  993. return 1;
  994. if( f1->scl > f2->scl )
  995. return -1;
  996. return 0;
  997. }
  998. /*
  999. De-allocates memory held by a descriptor histogram
  1000. @param hist pointer to a 2D array of orientation histograms
  1001. @param d width of hist
  1002. */
  1003. void release_descr_hist( double**** hist, int d )
  1004. {
  1005. int i, j;
  1006. for( i = 0; i < d; i++)
  1007. {
  1008. for( j = 0; j < d; j++ )
  1009. free( (*hist)[i][j] );
  1010. free( (*hist)[i] );
  1011. }
  1012. free( *hist );
  1013. *hist = NULL;
  1014. }
  1015. /*
  1016. De-allocates memory held by a scale space pyramid
  1017. @param pyr scale space pyramid
  1018. @param octvs number of octaves of scale space
  1019. @param n number of images per octave
  1020. */
  1021. void release_pyr( IplImage**** pyr, int octvs, int n )
  1022. {
  1023. int i, j;
  1024. for( i = 0; i < octvs; i++ )
  1025. {
  1026. for( j = 0; j < n; j++ )
  1027. cvReleaseImage( &(*pyr)[i][j] );
  1028. free( (*pyr)[i] );
  1029. }
  1030. free( *pyr );
  1031. *pyr = NULL;
  1032. }