contrib/oxl/mvl/HMatrix2DComputeRobust.cxx
Go to the documentation of this file.
00001 #include "HMatrix2DComputeRobust.h"
00002 //:
00003 // \file
00004 
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 = 0;
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   double std_in = stdev(residualsH);
00163 
00164   matches.set(inlier_list, point1_int, point2_int);
00165   int inlier_count = matches.compute_match_count();
00166   inliers_ = inlier_list;
00167   residuals_ = residualsH;
00168   vcl_cerr << "Residuals Variance : " << std_in << vcl_endl
00169            << "Inlier -\n"
00170            << "         " << inlier_count << vcl_endl;
00171 
00172   return true;
00173 }
00174 
00175 double HMatrix2DComputeRobust::stdev(vcl_vector<double>& residuals)
00176 {
00177   double ret = 0.0;
00178   for (int i = 0; i < data_size_; i++)
00179     ret += residuals[i];
00180 
00181   ret /= residuals.size();
00182   ret = vcl_sqrt(ret);
00183   return ret;
00184 }
00185 
00186 vcl_vector<double> HMatrix2DComputeRobust::calculate_residuals(vcl_vector<vgl_homg_point_2d<double> >& one,
00187                                                                vcl_vector<vgl_homg_point_2d<double> >& two,
00188                                                                HMatrix2D* H)
00189 {
00190   vcl_vector<double> ret(data_size_);
00191   for (int i = 0; i < data_size_; i++)
00192   {
00193     ret[i] = calculate_residual(one[i], two[i], H);
00194   }
00195   return ret;
00196 }
00197 
00198 vcl_vector<double> HMatrix2DComputeRobust::calculate_residuals(vcl_vector<HomgPoint2D>& one,
00199                                                                vcl_vector<HomgPoint2D>& two,
00200                                                                HMatrix2D* H)
00201 {
00202   vcl_vector<double> ret(data_size_);
00203   for (int i = 0; i < data_size_; i++)
00204   {
00205     ret[i] = calculate_residual(one[i], two[i], H);
00206   }
00207   return ret;
00208 }
00209 
00210 //:
00211 // \todo not yet implemented
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 //:
00221 // \todo not yet implemented
00222 double HMatrix2DComputeRobust::calculate_residual(vgl_homg_point_2d<double>& /*one*/,
00223                                                   vgl_homg_point_2d<double>& /*two*/,
00224                                                   HMatrix2D* /*H*/)
00225 {
00226   vcl_cerr << "HMatrix2DComputeRobust::calculate_residual() not yet implemented\n";
00227   return -1.0;
00228 }
00229 
00230 //:
00231 // \todo not yet implemented
00232 double HMatrix2DComputeRobust::calculate_residual(HomgPoint2D& /*one*/,
00233                                                   HomgPoint2D& /*two*/,
00234                                                   HMatrix2D* /*H*/)
00235 {
00236   vcl_cerr << "HMatrix2DComputeRobust::calculate_residual() not yet implemented\n";
00237   return 100.0;
00238 }