contrib/oxl/mvl/HMatrix2DComputeRobust.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 
00004 #include "HMatrix2DComputeRobust.h"
00005 #include <vcl_cassert.h>
00006 #include <vcl_iostream.h>
00007 #include <vcl_cmath.h>
00008 #include <vgl/vgl_homg_point_2d.h>
00009 #include <mvl/Probability.h>
00010 #include <mvl/AffineMetric.h>
00011 #include <mvl/HomgInterestPointSet.h>
00012 
00013 HMatrix2DComputeRobust::HMatrix2DComputeRobust() {}
00014 
00015 HMatrix2DComputeRobust::~HMatrix2DComputeRobust() {}
00016 
00017 
00018 HMatrix2D HMatrix2DComputeRobust::compute(PairMatchSetCorner& matches)
00019 {
00020   HMatrix2D H;
00021   if (compute(matches, &H))
00022     return H;
00023   else
00024     return HMatrix2D();
00025 }
00026 
00027 HMatrix2D HMatrix2DComputeRobust::compute(vcl_vector<HomgPoint2D>& points1, vcl_vector<HomgPoint2D>& points2)
00028 {
00029   if (points1.size() != points2.size())
00030     vcl_cerr << __FILE__ ": Point vectors are not of equal length\n";
00031   assert(points1.size() <= points2.size());
00032   HomgInterestPointSet p1(points1,0);
00033   HomgInterestPointSet p2(points2,0);
00034   PairMatchSetCorner matches(&p1, &p2);
00035   int count = matches.size();
00036   vcl_vector<bool> inliers(count, true);
00037   vcl_vector<int> ind1(count), ind2(count);
00038   for (int i = 0; i < count; i++)  ind1[i] = ind2[i] = i;
00039   matches.set(inliers, ind1, ind2);
00040 
00041   HMatrix2D H;
00042   if (compute(matches, &H))
00043     return H;
00044   else
00045     return HMatrix2D();
00046 }
00047 
00048 HMatrix2D HMatrix2DComputeRobust::compute(vcl_vector<vgl_homg_point_2d<double> >& points1,
00049                                           vcl_vector<vgl_homg_point_2d<double> >& points2)
00050 {
00051   if (points1.size() != points2.size())
00052     vcl_cerr << __FILE__ ": Point vectors are not of equal length\n";
00053   assert(points1.size() <= points2.size());
00054   HomgInterestPointSet p1(points1,0);
00055   HomgInterestPointSet p2(points2,0);
00056   PairMatchSetCorner matches(&p1, &p2);
00057   int count = matches.size();
00058   vcl_vector<bool> inliers(count, true);
00059   vcl_vector<int> ind1(count), ind2(count);
00060   for (int i = 0; i < count; i++)  ind1[i] = ind2[i] = i;
00061   matches.set(inliers, ind1, ind2);
00062 
00063   HMatrix2D H;
00064   if (compute(matches, &H))
00065     return H;
00066   else
00067     return HMatrix2D();
00068 }
00069 
00070 //-----------------------------------------------------------------------------
00071 //
00072 //: Compute a robust homography.
00073 //
00074 // Return false if the calculation fails.
00075 //
00076 bool HMatrix2DComputeRobust::compute(PairMatchSetCorner& matches, HMatrix2D *H)
00077 {
00078   // Copy matching points from matchset.
00079   // Set up some initial variables
00080   HomgInterestPointSet const* points1 = matches.get_corners1();
00081   HomgInterestPointSet const* points2 = matches.get_corners2();
00082   vcl_vector<HomgPoint2D> point1_store, point2_store;
00083   vcl_vector<int> point1_int, point2_int;
00084   matches.extract_matches(point1_store, point1_int, point2_store, point2_int);
00085   data_size_ = matches.count();
00086   vcl_vector<HomgPoint2D> point1_image(data_size_), point2_image(data_size_);
00087 
00088   for (int a = 0; a < data_size_; a++)
00089   {
00090     vnl_double_2 temp1;
00091     temp1 = points1->get_2d(point1_int[a]);
00092     point1_image[a] = HomgPoint2D(temp1[0], temp1[1], 1.0);
00093   }
00094 
00095   for (int a = 0; a < data_size_; a++)
00096   {
00097     vnl_double_2 temp2;
00098     temp2 = points2->get_2d(point2_int[a]);
00099     point2_image[a] = HomgPoint2D(temp2[0], temp2[1], 1.0);
00100   }
00101 
00102   HMatrix2D Hs;
00103   double Ds = 1e+10;
00104   int count;
00105   vcl_vector<bool> inlier_list(data_size_);
00106   vcl_vector<double> residualsH(data_size_, 100.0);
00107   // 300 random samples from the points set
00108   for (int i = 0; i < 100; i++)
00109   {
00110     vcl_vector<int> index(4);
00111     // Take the minimum sample of seven points for the F Matrix calculation
00112     index = Monte_Carlo(point1_store, point1_int, 8, 4);
00113     vcl_vector<HomgPoint2D> four1_homg(4);
00114     vcl_vector<HomgPoint2D> four2_homg(4);
00115     for (int j = 0; j < 4; j++)
00116     {
00117       int ind = index[j];
00118       vnl_double_2 p1 = points1->get_2d(ind);
00119       four1_homg[j] = HomgPoint2D(p1[0], p1[1], 1.0);
00120       int other = matches.get_match_12(ind);
00121       vnl_double_2 p2 = points2->get_2d(other);
00122       four2_homg[j] = HomgPoint2D(p2[0], p2[1], 1.0);
00123     }
00124 
00125     // Set up a new HMatrix 4 point Computor
00126     HMatrix2DCompute4Point Computor;
00127 
00128     // Compute H with preconditioned points
00129 //  HMatrix2D* H_temp_homg = new HMatrix2D();
00130 //  HMatrix2D* H_temp = new HMatrix2D();
00131 
00132     if (!Computor.compute(four1_homg, four2_homg, &Hs))
00133       vcl_cerr << "HMatrix2DCompute4Point - failure!\n";
00134 
00135     // De-condition H
00136 //    H_temp = new HMatrix2D(metric.homg_to_image_H(*H_temp_homg, metric, metric));
00137 
00138     // Now to for each relation calculate the MLE estimate and corresponding vector
00139     // of error terms
00140     int temp_count = 0;
00141     vcl_vector<bool> list(data_size_);
00142     vcl_vector<double> residuals = calculate_residuals(point1_image, point2_image, &Hs);
00143     double mle_error = calculate_term(residuals, list, temp_count);
00144     if (mle_error < Ds)
00145     {
00146 //    HMatrix2D Hs_homg = *H_temp_homg;
00147       Ds = mle_error;
00148       basis_ = index;
00149       inlier_list = list;
00150       residualsH = residuals;
00151       count = temp_count;
00152       vcl_cerr << "Minimum so far... : " << Ds << vcl_endl
00153                << "Inliers : " << count << vcl_endl
00154                << "HMatrix2D : " << Hs.get_matrix() << vcl_endl;
00155     }
00156   }
00157   vcl_cerr << "Final Figures...\n"
00158            << "Ds : " << Ds << vcl_endl
00159            << "HMatrix2D : " << Hs << vcl_endl;
00160   H->set(Hs.get_matrix());
00161 
00162   int inlier_count = count;
00163   double std_in = stdev(residualsH);
00164 
00165   matches.set(inlier_list, point1_int, point2_int);
00166   inlier_count = matches.compute_match_count();
00167   inliers_ = inlier_list;
00168   residuals_ = residualsH;
00169   vcl_cerr << "Residuals Variance : " << std_in << vcl_endl
00170            << "Inlier -\n"
00171            << "         " << inlier_count << vcl_endl;
00172 
00173   return true;
00174 }
00175 
00176 double HMatrix2DComputeRobust::stdev(vcl_vector<double>& residuals)
00177 {
00178   double ret = 0.0;
00179   for (int i = 0; i < data_size_; i++)
00180     ret += residuals[i];
00181 
00182   ret /= residuals.size();
00183   ret = vcl_sqrt(ret);
00184   return ret;
00185 }
00186 
00187 vcl_vector<double> HMatrix2DComputeRobust::calculate_residuals(vcl_vector<vgl_homg_point_2d<double> >& one,
00188                                                                vcl_vector<vgl_homg_point_2d<double> >& two,
00189                                                                HMatrix2D* H)
00190 {
00191   vcl_vector<double> ret(data_size_);
00192   for (int i = 0; i < data_size_; i++)
00193   {
00194     ret[i] = calculate_residual(one[i], two[i], H);
00195   }
00196   return ret;
00197 }
00198 
00199 vcl_vector<double> HMatrix2DComputeRobust::calculate_residuals(vcl_vector<HomgPoint2D>& one,
00200                                                                vcl_vector<HomgPoint2D>& two,
00201                                                                HMatrix2D* H)
00202 {
00203   vcl_vector<double> ret(data_size_);
00204   for (int i = 0; i < data_size_; i++)
00205   {
00206     ret[i] = calculate_residual(one[i], two[i], H);
00207   }
00208   return ret;
00209 }
00210 
00211 // TODO
00212 double HMatrix2DComputeRobust::calculate_term(vcl_vector<double>& /*residuals*/,
00213                                               vcl_vector<bool>& /*inlier_list*/,
00214                                               int& /*count*/)
00215 {
00216   vcl_cerr << "HMatrix2DComputeRobust::calculate_term() not yet implemented\n";
00217   return 10000.0;
00218 }
00219 
00220 // TODO
00221 double HMatrix2DComputeRobust::calculate_residual(vgl_homg_point_2d<double>& /*one*/,
00222                                                   vgl_homg_point_2d<double>& /*two*/,
00223                                                   HMatrix2D* /*H*/)
00224 {
00225   vcl_cerr << "HMatrix2DComputeRobust::calculate_residual() not yet implemented\n";
00226   return -1.0;
00227 }
00228 
00229 // TODO
00230 double HMatrix2DComputeRobust::calculate_residual(HomgPoint2D& /*one*/,
00231                                                   HomgPoint2D& /*two*/,
00232                                                   HMatrix2D* /*H*/)
00233 {
00234   vcl_cerr << "HMatrix2DComputeRobust::calculate_residual() not yet implemented\n";
00235   return 100.0;
00236 }