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