00001 #include "HMatrix2DComputeRobust.h"
00002
00003
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
00073
00074
00075
00076 bool HMatrix2DComputeRobust::compute(PairMatchSetCorner& matches, HMatrix2D *H)
00077 {
00078
00079
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
00108 for (int i = 0; i < 100; i++)
00109 {
00110 vcl_vector<int> index(4);
00111
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
00126 HMatrix2DCompute4Point Computor;
00127
00128
00129
00130
00131
00132 if (!Computor.compute(four1_homg, four2_homg, &Hs))
00133 vcl_cerr << "HMatrix2DCompute4Point - failure!\n";
00134
00135
00136
00137
00138
00139
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
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
00212 double HMatrix2DComputeRobust::calculate_term(vcl_vector<double>& ,
00213 vcl_vector<bool>& ,
00214 int& )
00215 {
00216 vcl_cerr << "HMatrix2DComputeRobust::calculate_term() not yet implemented\n";
00217 return 10000.0;
00218 }
00219
00220
00221
00222 double HMatrix2DComputeRobust::calculate_residual(vgl_homg_point_2d<double>& ,
00223 vgl_homg_point_2d<double>& ,
00224 HMatrix2D* )
00225 {
00226 vcl_cerr << "HMatrix2DComputeRobust::calculate_residual() not yet implemented\n";
00227 return -1.0;
00228 }
00229
00230
00231
00232 double HMatrix2DComputeRobust::calculate_residual(HomgPoint2D& ,
00233 HomgPoint2D& ,
00234 HMatrix2D* )
00235 {
00236 vcl_cerr << "HMatrix2DComputeRobust::calculate_residual() not yet implemented\n";
00237 return 100.0;
00238 }