Go to the documentation of this file.00001
00002 #ifndef vpgl_fm_compute_reg_ransac_cxx_
00003 #define vpgl_fm_compute_reg_ransac_cxx_
00004
00005 #include "vpgl_fm_compute_reg_ransac.h"
00006
00007 #include <vcl_iostream.h>
00008 #include <vcl_cassert.h>
00009 #include <vcl_cmath.h>
00010 #include <vgl/vgl_point_2d.h>
00011 #include <vgl/vgl_homg_point_2d.h>
00012 #include <vgl/vgl_homg_line_2d.h>
00013 #include <vgl/algo/vgl_homg_operators_2d.h>
00014 #include <rrel/rrel_ran_sam_search.h>
00015 #include <rrel/rrel_muset_obj.h>
00016
00017
00018
00019 bool
00020 vpgl_fm_compute_reg_ransac::compute(
00021 const vcl_vector< vgl_point_2d<double> >& pr,
00022 const vcl_vector< vgl_point_2d<double> >& pl,
00023 vpgl_reg_fundamental_matrix<double>& fm )
00024 {
00025
00026 if ( pr.size() < 1 || pl.size() < 1 ){
00027 vcl_cerr << "vpgl_fm_compute_ransac: Need at least 1 point pair.\n"
00028 << "Number in each set: " << pr.size() << ", " << pl.size() << vcl_endl;
00029 return false;
00030 }
00031
00032
00033 if ( pr.size() != pl.size() ){
00034 vcl_cerr << "vpgl_fm_compute_reg_ransac: Need correspondence lists of same size.\n";
00035 return false;
00036 }
00037
00038
00039 rrel_fm_reg_problem* estimator = new rrel_fm_reg_problem( pr, pl );
00040 estimator->verbose=true;
00041 rrel_muset_obj* ransac = new rrel_muset_obj((int)vcl_floor(pr.size()*.75));
00042 estimator->set_prior_scale( 1.0 );
00043 rrel_ran_sam_search* ransam = new rrel_ran_sam_search;
00044 ransam->set_trace_level(params_->trace_level);
00045 ransam->set_sampling_params( params_->max_outlier_frac,
00046 params_->desired_prob_good,
00047 params_->max_pops );
00048 bool ransac_succeeded = ransam->estimate( estimator, ransac );
00049
00050 if ( ransac_succeeded )
00051 estimator->params_to_fm( ransam->params(), fm );
00052
00053
00054 vcl_vector<double> residuals;
00055 estimator->compute_residuals( ransam->params(), residuals );
00056
00057 outliers = vcl_vector<bool>();
00058 for ( unsigned i = 0; i < pr.size(); i++ ){
00059 if ( residuals[i] > params_->residual_thresh )
00060 outliers.push_back( true );
00061 else
00062 outliers.push_back( false );
00063 }
00064
00065 delete ransac;
00066 delete ransam;
00067 delete estimator;
00068
00069 return ransac_succeeded;
00070 }
00071
00072
00073
00074 vpgl_fm_compute_reg_ransac_params::vpgl_fm_compute_reg_ransac_params() :
00075 max_outlier_frac(0.5),
00076 desired_prob_good(0.99),
00077 max_pops(1),
00078 trace_level(0),
00079 residual_thresh(1)
00080 {
00081 }
00082
00083
00084
00085 rrel_fm_reg_problem::rrel_fm_reg_problem(
00086 const vcl_vector< vgl_point_2d<double> >& pr,
00087 const vcl_vector< vgl_point_2d<double> >& pl ) :
00088 rrel_estimation_problem(2,1)
00089 {
00090 assert( pr.size() == pl.size() );
00091
00092 for ( unsigned int i=0; i < pr.size(); i++ )
00093 {
00094 pr_.push_back( pr[i] );
00095 pl_.push_back( pl[i] );
00096 }
00097 verbose = false;
00098 }
00099
00100
00101
00102 bool
00103 rrel_fm_reg_problem::fit_from_minimal_set(
00104 const vcl_vector<int>& point_indices,
00105 vnl_vector<double>& params ) const
00106 {
00107 if ( verbose ) vcl_cerr << "rrel_fm_reg_problem::fit_from_minimal_set\n";
00108 assert( point_indices.size() == 1 );
00109
00110 vpgl_reg_fundamental_matrix<double> fm( pr_[point_indices[0]], pl_[point_indices[0]] );
00111
00112
00113
00114 fm_to_params( fm, params );
00115 if ( verbose ) vcl_cerr << "params: " << params << '\n';
00116 return true;
00117 }
00118
00119
00120
00121 void
00122 rrel_fm_reg_problem::compute_residuals(
00123 const vnl_vector<double>& params,
00124 vcl_vector<double>& residuals ) const
00125 {
00126 if ( verbose ) vcl_cerr << "rrel_fm_reg_problem::compute_residuals\n";
00127
00128 vpgl_reg_fundamental_matrix<double> fm;
00129 params_to_fm(params, fm);
00130
00131 if ( residuals.size() != pr_.size() )
00132 residuals.resize( pr_.size() );
00133
00134
00135
00136 for ( unsigned i = 0; i < pr_.size(); i++ ){
00137 vgl_homg_line_2d<double> lr =
00138 fm.r_epipolar_line( vgl_homg_point_2d<double>( pl_[i] ) );
00139 vgl_homg_line_2d<double> ll =
00140 fm.l_epipolar_line( vgl_homg_point_2d<double>( pr_[i] ) );
00141 residuals[i] = vgl_homg_operators_2d<double>::perp_dist_squared( lr,
00142 vgl_homg_point_2d<double>( pr_[i] ) )
00143 + vgl_homg_operators_2d<double>::perp_dist_squared( ll,
00144 vgl_homg_point_2d<double>( pl_[i] ) );
00145 }
00146 }
00147
00148
00149
00150 void
00151 rrel_fm_reg_problem::fm_to_params(
00152 const vpgl_reg_fundamental_matrix<double>& fm,
00153 vnl_vector<double>& p ) const
00154 {
00155 p.set_size(2);
00156 vnl_matrix_fixed<double,3,3> fm_vnl = fm.get_matrix();
00157 p(0) = fm_vnl(0,2);
00158 p(1) = fm_vnl(2,1);
00159 }
00160
00161
00162
00163 void
00164 rrel_fm_reg_problem::params_to_fm(
00165 const vnl_vector<double>& p,
00166 vpgl_reg_fundamental_matrix<double>& fm ) const
00167 {
00168 fm.set_from_params( p(0), p(1) );
00169 }
00170
00171
00172
00173 bool
00174 rrel_fm_reg_problem::weighted_least_squares_fit(
00175 vnl_vector<double>& ,
00176 vnl_matrix<double>& ,
00177 const vcl_vector<double>* ) const
00178 {
00179 vcl_cerr << "rrel_fm_reg_problem::weighted_least_squares_fit was called, but is not implemented.\n";
00180 return false;
00181 }
00182
00183
00184 #endif // vpgl_fm_compute_reg_ransac_cxx_