contrib/gel/geml/geml_matcher_correlation.cxx
Go to the documentation of this file.
00001 // This is gel/geml/geml_matcher_correlation.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 #include "geml_matcher_correlation.h"
00006 //:
00007 // \file
00008 // \author Geoffrey Cross, Oxford RRG
00009 // \verbatim
00010 //  Modifications:
00011 //   Geoff Initial version.
00012 // \endverbatim
00013 //-----------------------------------------------------------------------------
00014 
00015 #include <vcl_iostream.h>
00016 #include <vnl/vnl_math.h>
00017 #include <vnl/vnl_matrix.h>
00018 
00019 #include <vil1/vil1_memory_image_window.h>
00020 
00021 #define MAX_CORNER_ERROR 1
00022 #define CORRELATION_KERNEL 3
00023 #define NORMALISED_CORRELATION false
00024 #define SEARCH_WINDOW_X 50
00025 #define SEARCH_WINDOW_Y 50
00026 #define NO_SCORE -2
00027 
00028 geml_matcher_correlation::geml_matcher_correlation( const vil1_memory_image_of<vxl_byte> image1,
00029                                                     const vil1_memory_image_of<vxl_byte> image2,
00030                                                     const vcl_vector< vcl_pair<float,float> > &corners1,
00031                                                     const vcl_vector< vcl_pair<float,float> > &corners2)
00032   : geml_matcher( image1, image2, corners1, corners2)
00033 {
00034 }
00035 
00036 
00037 vcl_vector< vcl_pair<int,int> > geml_matcher_correlation::get_matches()
00038 {
00039   // correlate each corner against each corner
00040   vnl_matrix<double> scores1to2(corners1_.size(),corners2_.size());
00041   vnl_matrix<double> scores2to1(corners2_.size(),corners1_.size());
00042 
00043   for (unsigned int i=0; i< corners1_.size(); ++i)
00044   {
00045     double x1= corners1_[i].first;
00046     double y1= corners1_[i].second;
00047 
00048     for (unsigned int j=0; j< corners2_.size(); ++j)
00049     {
00050       double x2= corners2_[j].first;
00051       double y2= corners2_[j].second;
00052 
00053       if (vnl_math_abs(x1-x2) < SEARCH_WINDOW_X && vnl_math_abs(y1-y2) < SEARCH_WINDOW_Y)
00054       {
00055         vcl_pair<double,double> scores= best_local_correlation_score( i, j);
00056 
00057         scores1to2.put( i, j, scores.first);
00058         scores2to1.put( j, i, scores.second);
00059       }
00060       else
00061       {
00062         scores1to2.put( i, j, NO_SCORE);
00063         scores2to1.put( j, i, NO_SCORE);
00064       }
00065     }
00066   }
00067 
00068   // look for best match to first image corners
00069   vcl_vector<int> bestimage1match( corners1_.size());
00070   vcl_vector<double> bestimage1score( corners1_.size());
00071 
00072   for (unsigned int i=0; i< corners1_.size(); ++i)
00073   {
00074     double bestscore= NO_SCORE;
00075     int bestmatch= -1;
00076 
00077     for (unsigned int j=0; j< corners2_.size(); ++j)
00078     {
00079       if (bestscore== NO_SCORE)
00080       {
00081         bestscore= scores1to2( i, j);
00082         bestmatch= j;
00083       }
00084       else if (bestscore>scores1to2(i,j) && scores1to2(i,j)!=NO_SCORE)
00085       {
00086         bestscore= scores1to2( i, j);
00087         bestmatch= j;
00088       }
00089     }
00090 
00091     bestimage1match[i]= bestmatch;
00092     bestimage1score[i]= bestscore;
00093   }
00094 
00095   // look for best match to second image corners
00096   vcl_vector<int> bestimage2match( corners2_.size());
00097   vcl_vector<double> bestimage2score( corners2_.size());
00098 
00099   for (unsigned int i=0; i< corners2_.size(); ++i)
00100   {
00101     double bestscore= NO_SCORE;
00102     int bestmatch= -1;
00103 
00104     for (unsigned int j=0; j< corners1_.size(); ++j)
00105     {
00106       if (bestscore== NO_SCORE)
00107       {
00108         bestscore= scores2to1( i, j);
00109         bestmatch= j;
00110       }
00111       else if (bestscore>scores2to1(i,j) && scores2to1(i,j)!=NO_SCORE)
00112       {
00113         bestscore= scores2to1( i, j);
00114         bestmatch= j;
00115       }
00116     }
00117 
00118     bestimage2match[i]= bestmatch;
00119     bestimage2score[i]= bestscore;
00120   }
00121 
00122   // and check that the best match from image 1 to 2 is the
00123   //  same as the best match from image 2 to 1
00124 
00125   vcl_vector< vcl_pair<int,int> > l;
00126 
00127   for (unsigned int i=0; i< corners1_.size(); i++)
00128   {
00129     int a= bestimage1match[i];
00130     int b= bestimage2match[a];
00131 
00132     if ((int)i==b)
00133     {
00134       vcl_cerr << i << ' ' << a << vcl_endl;
00135       vcl_cout << corners1_[i].first << ' ' << corners1_[i].second << ' '
00136                << corners2_[a].first << ' ' << corners2_[a].second << vcl_endl;
00137       l.push_back( vcl_pair<int,int>(i,a) );
00138     }
00139   }
00140 
00141   //  vcl_cerr << bestimage1match << vcl_endl;
00142   //  vcl_cerr << bestimage2match << vcl_endl;
00143 
00144   return l;
00145 }
00146 
00147 
00148 // search in a small window (about 3x3) for the best correlation between a pair of corners
00149 vcl_pair<double,double> geml_matcher_correlation::best_local_correlation_score( const int c1, const int c2)
00150 {
00151   double x1= corners1_[c1].first;
00152   double y1= corners1_[c1].second;
00153   double x2= corners2_[c2].first;
00154   double y2= corners2_[c2].second;
00155   double bestscore1= -1;
00156   double bestscore2= -1;
00157 
00158   vil1_memory_image_window w1( im1_, int(x1), int(y1), CORRELATION_KERNEL);
00159   vil1_memory_image_window w2( im2_, int(x2), int(y2), CORRELATION_KERNEL);
00160 
00161   for (int x= -MAX_CORNER_ERROR; x<= MAX_CORNER_ERROR; x++)
00162   {
00163     for (int y= -MAX_CORNER_ERROR; y<= MAX_CORNER_ERROR; y++)
00164     {
00165       double score1, score2;
00166 
00167   //  score1= w1.sum_squared_differences(im2_, x2+ x, y2+ y);
00168   //  score2= w2.sum_squared_differences(im1_, x1+ x, y1+ y);
00169       score1= w1.normalised_cross_correlation(im2_, int(x2+ x), int(y2+ y));
00170       score2= w2.normalised_cross_correlation(im1_, int(x1+ x), int(y1+ y));
00171 
00172       if (score1<bestscore1 || bestscore1<0)
00173         bestscore1= score1;
00174 
00175       if (score2<bestscore2 || bestscore2<0)
00176         bestscore2= score2;
00177     }
00178   }
00179 
00180   return vcl_pair<double,double>(bestscore1,bestscore2);
00181 }