00001 #include "sift.h"
00002 #include "imgfeatures.h"
00003 #include "kdtree.h"
00004 #include "utils.h"
00005 #include "xform.h"
00006
00007 #include "opencv/cv.h"
00008 #include "opencv/highgui.h"
00009
00010 #include <stdio.h>
00011
00012
00013
00014 #define KDTREE_BBF_MAX_NN_CHKS 200
00015
00016
00017 #define NN_SQ_DIST_RATIO_THR 0.49
00018
00019
00020 int main( int argc, char** argv )
00021 {
00022 IplImage* img1, * img2, * stacked;
00023 struct feature* feat1, * feat2, * feat;
00024 struct feature** nbrs;
00025 struct kd_node* kd_root;
00026 CvPoint pt1, pt2;
00027 double d0, d1;
00028 int n1, n2, k, i, m = 0;
00029
00030
00031 img1 = cvLoadImage( argv[1], 1 );
00032 img2 = cvLoadImage( argv[2], 1 );
00033 stacked = stack_imgs( img1, img2 );
00034
00035 n1 = sift_features( img1, &feat1 );
00036 n2 = sift_features( img2, &feat2 );
00037 kd_root = kdtree_build( feat2, n2 );
00038 for( i = 0; i < n1; i++ )
00039 {
00040 feat = feat1 + i;
00041 k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS );
00042 if( k == 2 )
00043 {
00044 d0 = descr_dist_sq( feat, nbrs[0] );
00045 d1 = descr_dist_sq( feat, nbrs[1] );
00046 if( d0 < d1 * NN_SQ_DIST_RATIO_THR )
00047 {
00048 pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) );
00049 pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) );
00050 pt2.y += img1->height;
00051 cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 );
00052 m++;
00053 feat1[i].fwd_match = nbrs[0];
00054 }
00055 }
00056 free( nbrs );
00057 }
00058
00059 fprintf( stderr, "Found %d total matches\n", m );
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 CvMat* H;
00074 IplImage* xformed;
00075 H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01,
00076 homog_xfer_err, 3.0, NULL, NULL );
00077 int inteval = 30;
00078 CvMat *coordinates = 0, *coordinates_t= 0;
00079 int step = 0;
00080 double *ptr = NULL;
00081 int row = 0, col = 0;
00082 if( H )
00083 {
00084 int control_points_number = ceil((double)img1->height/inteval)*2+ ceil((double)img1->width/inteval)*2;
00085 coordinates = cvCreateMat(control_points_number, 3 , CV_64FC1);
00086 coordinates_t = cvCreateMat(3 ,control_points_number, CV_64FC1);
00087 step = coordinates->step/sizeof(double);
00088 ptr = coordinates->data.db;
00089 i = 0;
00090 for (row = inteval; row < img1->height; row+=inteval){
00091 (ptr+i*step)[0] = 0;
00092 (ptr+i*step)[1] = row;
00093 (ptr+i*step)[2] = 1;
00094 cvCircle(stacked, cvPoint((ptr+i*step)[0], (ptr+i*step)[1]), 2, CV_RGB(0,255,0), 2, 8, 0);
00095 i++;
00096 }
00097 (ptr+i*step)[0] = 0;
00098 (ptr+i*step)[1] = img1->height;
00099 (ptr+i*step)[2] = 1;
00100 cvCircle(stacked, cvPoint((ptr+i*step)[0], (ptr+i*step)[1]), 2, CV_RGB(0,255,0), 2, 8, 0);
00101 i++;
00102
00103 for (col = inteval; col < img1->width; col+=inteval){
00104 (ptr+i*step)[0] = col;
00105 (ptr+i*step)[1] = img1->height;
00106 (ptr+i*step)[2] = 1;
00107 cvCircle(stacked, cvPoint((ptr+i*step)[0], (ptr+i*step)[1]), 2, CV_RGB(0,255,0), 2, 8, 0);
00108 i++;
00109 }
00110 (ptr+i*step)[0] = img1->width;
00111 (ptr+i*step)[1] = img1->height;
00112 (ptr+i*step)[2] = 1;
00113 cvCircle(stacked, cvPoint((ptr+i*step)[0], (ptr+i*step)[1]), 2, CV_RGB(0,255,0), 2, 8, 0);
00114 i++;
00115
00116 for (row = img1->height - inteval; row > 0 ; row-=inteval){
00117 (ptr+i*step)[0] = img1->width;
00118 (ptr+i*step)[1] = row;
00119 (ptr+i*step)[2] = 1;
00120 cvCircle(stacked, cvPoint((ptr+i*step)[0], (ptr+i*step)[1]), 2, CV_RGB(0,255,0), 2, 8, 0);
00121 i++;
00122 }
00123 (ptr+i*step)[0] = img1->width;
00124 (ptr+i*step)[1] = 0;
00125 (ptr+i*step)[2] = 1;
00126 cvCircle(stacked, cvPoint((ptr+i*step)[0], (ptr+i*step)[1]), 2, CV_RGB(0,255,0), 2, 8, 0);
00127 i++;
00128 for (col = img1->width-inteval; col > 0; col-=inteval){
00129 (ptr+i*step)[0] = col;
00130 (ptr+i*step)[1] = 0;
00131 (ptr+i*step)[2] = 1;
00132 cvCircle(stacked, cvPoint((ptr+i*step)[0], (ptr+i*step)[1]), 2, CV_RGB(0,255,0), 2, 8, 0);
00133 i++;
00134 }
00135 (ptr+i*step)[0] = 0;
00136 (ptr+i*step)[1] = 0;
00137 (ptr+i*step)[2] = 1;
00138 cvCircle(stacked, cvPoint((ptr+i*step)[0], (ptr+i*step)[1]), 2, CV_RGB(0,255,0), 2, 8, 0);
00139 i++;
00140 }
00141 cvGEMM(H, coordinates, 1, 0,0, coordinates_t, CV_GEMM_B_T);
00142
00143 cvTranspose(coordinates_t, coordinates);
00144 ptr = coordinates->data.db;
00145 for (row = 0; row < coordinates->rows; ++row)
00146 {
00147 cvCircle(stacked, cvPoint((ptr+step*row)[0]/(ptr+step*row)[2], (ptr+step*row)[1]/(ptr+step*row)[2] + img1->height), 2, CV_RGB(0,255,0), 2, 8, 0);
00148 }
00149 cvNamedWindow( "SIFT", 1 );
00150 cvShowImage( "SIFT", stacked);
00151 char newfilename[100];
00152 for (i = 0; i < 10; ++i){
00153 snprintf(newfilename, 100, "stacked%d.png",i);
00154 cvSaveImage(newfilename, stacked, 0);
00155 }
00156
00157 cvWaitKey( 0 );
00158 cvReleaseImage( &xformed );
00159 cvReleaseMat( &H );
00160
00161 cvReleaseImage( &stacked );
00162 cvReleaseImage( &img1 );
00163 cvReleaseImage( &img2 );
00164 kdtree_release( kd_root );
00165 free( feat1 );
00166 free( feat2 );
00167 return 0;
00168 }