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