00001 #include "FMatrixComputeRobust.h"
00002 #include <mvl/Probability.h>
00003 #include <mvl/HomgNorm2D.h>
00004 #include <mvl/HomgOperator2D.h>
00005 #include <mvl/HomgInterestPointSet.h>
00006 #include <mvl/FMatrixCompute7Point.h>
00007 #include <vnl/vnl_double_2.h>
00008 #include <vnl/vnl_double_3x3.h>
00009 #include <vcl_iostream.h>
00010 #include <vcl_cmath.h>
00011
00012 FMatrixComputeRobust::FMatrixComputeRobust() {}
00013
00014 FMatrixComputeRobust::~FMatrixComputeRobust() {}
00015
00016
00017
00018
00019
00020
00021
00022 bool FMatrixComputeRobust::compute(PairMatchSetCorner& matches, FMatrix *F)
00023 {
00024 inliers_.resize(0);
00025 residuals_.resize(0);
00026
00027
00028
00029 HomgInterestPointSet const* points1 = matches.get_corners1();
00030 HomgInterestPointSet const* points2 = matches.get_corners2();
00031 vcl_vector<HomgPoint2D> point1_store, point2_store;
00032 vcl_vector<int> point1_int, point2_int;
00033 matches.extract_matches(point1_store, point1_int, point2_store, point2_int);
00034 data_size_ = matches.count();
00035 vcl_vector<HomgPoint2D> point1_image(data_size_), point2_image(data_size_);
00036
00037
00038 for (int a = 0; a < data_size_; a++) {
00039 vnl_double_2 temp1;
00040 temp1 = points1->get_2d(point1_int[a]);
00041 point1_image[a] = HomgPoint2D(temp1[0], temp1[1], 1.0);
00042 }
00043
00044 for (int a = 0; a < data_size_; a++) {
00045 vnl_double_2 temp2;
00046 temp2 = points2->get_2d(point2_int[a]);
00047 point2_image[a] = HomgPoint2D(temp2[0], temp2[1], 1.0);
00048 }
00049
00050 FMatrix Fs;
00051 double Ds = 1e+10;
00052 int count = 0;
00053 vcl_vector<bool> inlier_list(data_size_, false);
00054 vcl_vector<double> residualsF(data_size_, 100.0);
00055
00056
00057 for (int i = 0; i < 100; i++) {
00058 vcl_vector<int> index(7);
00059
00060
00061 index = Monte_Carlo(point1_store, point1_int, 8, 7);
00062 vcl_vector<HomgPoint2D> seven1(7);
00063 vcl_vector<HomgPoint2D> seven2(7);
00064 for (int j = 0; j < 7; j++) {
00065 vnl_double_2 t1 = points1->get_2d(index[j]);
00066 seven1[j] = HomgPoint2D(t1[0], t1[1], 1.0);
00067 int other = matches.get_match_12(index[j]);
00068 vnl_double_2 t2 = points2->get_2d(other);
00069 seven2[j] = HomgPoint2D(t2[0], t2[1], 1.0);
00070 }
00071
00072
00073
00074 FMatrixCompute7Point Computor(true, rank2_truncate_);
00075
00076
00077 vcl_vector<FMatrix*> F_temp;
00078 if (!Computor.compute(seven1, seven2, F_temp))
00079 vcl_cerr << "Seven point failure\n";
00080
00081 for (unsigned int k = 0; k < F_temp.size(); k++) {
00082 int temp_count = 0;
00083 vcl_vector<bool> list(data_size_);
00084 vcl_vector<double> residuals = calculate_residuals(point1_image, point2_image, F_temp[k]);
00085 double term_error = calculate_term(residuals, list, temp_count);
00086 if (term_error < Ds) {
00087 Fs = *F_temp[k];
00088 Ds = term_error;
00089 basis_ = index;
00090 inlier_list = list;
00091 residualsF = residuals;
00092 count = temp_count;
00093 }
00094 }
00095
00096 for (unsigned int k = 0; k < F_temp.size(); k++)
00097 delete F_temp[k];
00098 }
00099 vcl_cerr << "Final Figures...\n";
00100 vcl_cerr << "Ds : " << Ds << vcl_endl;
00101 vnl_double_3x3 sample = Fs.get_matrix();
00102 HomgPoint2D one, two;
00103 Fs.get_epipoles(&one, &two);
00104 vnl_double_2 o = one.get_double2();
00105 vnl_double_2 t = two.get_double2();
00106 HomgPoint2D c1(o[0], o[1], 1.0);
00107 HomgPoint2D c2(t[0], t[1], 1.0);
00108 vcl_cerr << "Epipole 1 : " << c1 << " Epipole 2 : " << c2 << vcl_endl;
00109 vcl_cerr << vcl_endl;
00110 epipole1_ = c1;
00111 epipole2_ = c2;
00112 sample /= sample.get(2, 2);
00113 vcl_cerr << "FMatrix : " << sample << vcl_endl;
00114 F->set(Fs.get_matrix());
00115
00116 int inlier_count = count;
00117 double std_in = 0.0;
00118
00119 for (int k = 0; k < data_size_; k++) {
00120 if (inlier_list[k]) {
00121 std_in += residualsF[k];
00122 }
00123 }
00124 std_in /= inlier_count;
00125 std_in = vcl_sqrt(std_in);
00126
00127
00128 matches.set(inlier_list, point1_int, point2_int);
00129 #if 0
00130 for (int z=0, k=0; z < inlier_list.size(); z++)
00131 if (inlier_list[z]) {
00132 vcl_cerr << "residualsF[" << z << "] : " << residualsF[z] << vcl_endl;
00133 vcl_cerr << k++ << vcl_endl;
00134 }
00135 #endif
00136 inliers_ = inlier_list;
00137 residuals_ = residualsF;
00138 vcl_cerr << "Inlier -\n";
00139 vcl_cerr << " std : " << std_in << vcl_endl;
00140 vcl_cerr << " " << inlier_count << "/" << data_size_ << vcl_endl;
00141 return true;
00142 }
00143
00144
00145 vcl_vector<double> FMatrixComputeRobust::calculate_residuals(vcl_vector<vgl_homg_point_2d<double> >& one,
00146 vcl_vector<vgl_homg_point_2d<double> >& two,
00147 FMatrix* F) {
00148 vcl_vector<double> ret(data_size_);
00149 for (int i = 0; i < data_size_; i++) {
00150 double val = calculate_residual(one[i], two[i], F);
00151 ret[i] = val;
00152 }
00153 return ret;
00154 }
00155
00156
00157 vcl_vector<double> FMatrixComputeRobust::calculate_residuals(vcl_vector<HomgPoint2D>& one,
00158 vcl_vector<HomgPoint2D>& two,
00159 FMatrix* F) {
00160 vcl_vector<double> ret(data_size_);
00161 for (int i = 0; i < data_size_; i++) {
00162 double val = calculate_residual(one[i], two[i], F);
00163 ret[i] = val;
00164 }
00165 return ret;
00166 }
00167
00168
00169 double FMatrixComputeRobust::stdev(vcl_vector<double>& residuals) {
00170 double ret = 0.0;
00171 for (int i = 0; i < data_size_; i++)
00172 ret += residuals[i];
00173
00174 ret /= residuals.size();
00175 ret = vcl_sqrt(ret);
00176 return ret;
00177 }
00178
00179
00180 double FMatrixComputeRobust::calculate_term(vcl_vector<double>& ,
00181 vcl_vector<bool>& ,
00182 int& ) {
00183 vcl_cerr << "FMatrixComputeRobust::calculate_term() not yet implemented\n";
00184 return 10000.0;
00185 }
00186
00187
00188 double FMatrixComputeRobust::calculate_residual(vgl_homg_point_2d<double>& ,
00189 vgl_homg_point_2d<double>& ,
00190 FMatrix* ) {
00191 vcl_cerr << "FMatrixComputeRobust::calculate_residual() not yet implemented\n";
00192 return 100.0;
00193 }
00194
00195
00196 double FMatrixComputeRobust::calculate_residual(HomgPoint2D& ,
00197 HomgPoint2D& ,
00198 FMatrix* ) {
00199 vcl_cerr << "FMatrixComputeRobust::calculate_residual() not yet implemented\n";
00200 return 100.0;
00201 }