/libs/vision/src/sift-hess/match.c

http://github.com/gamman/MRPT · C · 123 lines · 66 code · 17 blank · 40 comment · 6 complexity · 8d797655e5002ec9e48ad31eaaf5cf64 MD5 · raw file

  1. /*
  2. Detects SIFT features in two images and finds matches between them.
  3. Copyright (C) 2006 Rob Hess <hess@eecs.oregonstate.edu>
  4. @version 1.1.1-20070913
  5. */
  6. #include "sift.h"
  7. #include "imgfeatures.h"
  8. #include "kdtree.h"
  9. #include "utils.h"
  10. #include "xform.h"
  11. #include <cv.h>
  12. #include <cxcore.h>
  13. #include <highgui.h>
  14. #include <stdio.h>
  15. /* the maximum number of keypoint NN candidates to check during BBF search */
  16. #define KDTREE_BBF_MAX_NN_CHKS 200
  17. /* threshold on squared ratio of distances between NN and 2nd NN */
  18. #define NN_SQ_DIST_RATIO_THR 0.49
  19. /******************************** Globals ************************************/
  20. char img1_file[] = "..\\beaver.png";
  21. char img2_file[] = "..\\beaver_xform.png";
  22. /********************************** Main *************************************/
  23. int main( int argc, char** argv )
  24. {
  25. IplImage* img1, * img2, * stacked;
  26. struct feature* feat1, * feat2, * feat;
  27. struct feature** nbrs;
  28. struct kd_node* kd_root;
  29. CvPoint pt1, pt2;
  30. double d0, d1;
  31. int n1, n2, k, i, m = 0;
  32. img1 = cvLoadImage( img1_file, 1 );
  33. if( ! img1 )
  34. fatal_error( "unable to load image from %s", img1_file );
  35. img2 = cvLoadImage( img2_file, 1 );
  36. if( ! img2 )
  37. fatal_error( "unable to load image from %s", img2_file );
  38. stacked = stack_imgs( img1, img2 );
  39. fprintf( stderr, "Finding features in %s...\n", img1_file );
  40. n1 = sift_features( img1, &feat1 );
  41. fprintf( stderr, "Finding features in %s...\n", img2_file );
  42. n2 = sift_features( img2, &feat2 );
  43. kd_root = kdtree_build( feat2, n2 );
  44. for( i = 0; i < n1; i++ )
  45. {
  46. feat = feat1 + i;
  47. k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS );
  48. if( k == 2 )
  49. {
  50. d0 = descr_dist_sq( feat, nbrs[0] );
  51. d1 = descr_dist_sq( feat, nbrs[1] );
  52. if( d0 < d1 * NN_SQ_DIST_RATIO_THR )
  53. {
  54. pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) );
  55. pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) );
  56. pt2.y += img1->height;
  57. cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 );
  58. m++;
  59. feat1[i].fwd_match = nbrs[0];
  60. }
  61. }
  62. free( nbrs );
  63. }
  64. fprintf( stderr, "Found %d total matches\n", m );
  65. cvNamedWindow( "Matches", 1 );
  66. cvShowImage( "Matches", stacked );
  67. cvWaitKey( 0 );
  68. /*
  69. UNCOMMENT BELOW TO SEE HOW RANSAC FUNCTION WORKS
  70. Note that this line above:
  71. feat1[i].fwd_match = nbrs[0];
  72. is important for the RANSAC function to work.
  73. */
  74. /*
  75. {
  76. CvMat* H;
  77. H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01,
  78. homog_xfer_err, 3.0, NULL, NULL );
  79. if( H )
  80. {
  81. IplImage* xformed;
  82. xformed = cvCreateImage( cvGetSize( img2 ), IPL_DEPTH_8U, 3 );
  83. cvWarpPerspective( img1, xformed, H,
  84. CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS,
  85. cvScalarAll( 0 ) );
  86. cvNamedWindow( "Xformed", 1 );
  87. cvShowImage( "Xformed", xformed );
  88. cvWaitKey( 0 );
  89. cvReleaseImage( &xformed );
  90. cvReleaseMat( &H );
  91. }
  92. }
  93. */
  94. cvReleaseImage( &stacked );
  95. cvReleaseImage( &img1 );
  96. cvReleaseImage( &img2 );
  97. kdtree_release( kd_root );
  98. free( feat1 );
  99. free( feat2 );
  100. return 0;
  101. }