Go to the documentation of this file.00001
00002 #ifndef vpgl_fm_compute_affine_ransac_cxx_
00003 #define vpgl_fm_compute_affine_ransac_cxx_
00004
00005 #include "vpgl_fm_compute_affine_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 <vnl/algo/vnl_svd.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_affine_ransac::compute(
00022 const vcl_vector< vgl_point_2d<double> >& pr,
00023 const vcl_vector< vgl_point_2d<double> >& pl,
00024 vpgl_affine_fundamental_matrix<double>& fm )
00025 {
00026
00027 if ( pr.size() < 4 || pl.size() < 4 ){
00028 vcl_cerr << "vpgl_fm_compute_ransac: Need at least 4 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_affine_ransac: Need correspondence lists of same size.\n";
00036 return false;
00037 }
00038
00039
00040 rrel_fm_affine_problem* estimator = new rrel_fm_affine_problem( pr, pl );
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_affine_ransac_params::vpgl_fm_compute_affine_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_affine_problem::rrel_fm_affine_problem(
00086 const vcl_vector< vgl_point_2d<double> >& pr,
00087 const vcl_vector< vgl_point_2d<double> >& pl ) :
00088 rrel_estimation_problem(4,4)
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 }
00098
00099
00100
00101 bool
00102 rrel_fm_affine_problem::fit_from_minimal_set(
00103 const vcl_vector<int>& point_indices,
00104 vnl_vector<double>& params ) const
00105 {
00106 if ( verbose ) vcl_cerr << "rrel_fm_affine_problem::fit_from_minimal_set\n";
00107 assert( point_indices.size() == 4 );
00108
00109 vnl_matrix<double> S(4,5);
00110 for ( int i = 0; i < 4; i++ ){
00111 S(i,0)=pr_[point_indices[i]].x(); S(i,1)=pr_[point_indices[i]].y();
00112 S(i,2)=1;
00113 S(i,3)=pl_[point_indices[i]].y(); S(i,4)=pl_[point_indices[i]].x();
00114 }
00115 vnl_svd<double> svdS( S );
00116 params = svdS.nullvector();
00117
00118 if ( verbose ) vcl_cerr << "params: " << params << '\n';
00119 return true;
00120 }
00121
00122
00123
00124 void
00125 rrel_fm_affine_problem::compute_residuals(
00126 const vnl_vector<double>& params,
00127 vcl_vector<double>& residuals ) const
00128 {
00129 if ( verbose ) vcl_cerr << "rrel_fm_affine_problem::compute_residuals: ";
00130
00131 vpgl_affine_fundamental_matrix<double> fm;
00132 params_to_fm(params, fm);
00133
00134 if ( residuals.size() != pr_.size() )
00135 residuals.resize( pr_.size() );
00136 double ressum = 0;
00137
00138
00139
00140 for ( unsigned i = 0; i < pr_.size(); i++ ){
00141 vgl_homg_line_2d<double> lr =
00142 fm.r_epipolar_line( vgl_homg_point_2d<double>( pl_[i] ) );
00143 vgl_homg_line_2d<double> ll =
00144 fm.l_epipolar_line( vgl_homg_point_2d<double>( pr_[i] ) );
00145 residuals[i] = vgl_homg_operators_2d<double>::perp_dist_squared( lr,
00146 vgl_homg_point_2d<double>( pr_[i] ) )
00147 + vgl_homg_operators_2d<double>::perp_dist_squared( ll,
00148 vgl_homg_point_2d<double>( pl_[i] ) );
00149 ressum+=residuals[i];
00150 }
00151 if ( verbose ) vcl_cerr << ressum << '\n';
00152 }
00153
00154
00155
00156 void
00157 rrel_fm_affine_problem::fm_to_params(
00158 const vpgl_affine_fundamental_matrix<double>& fm,
00159 vnl_vector<double>& p ) const
00160 {
00161 p.set_size(2);
00162 vnl_matrix_fixed<double,3,3> fm_vnl = fm.get_matrix();
00163 p(0) = fm_vnl(2,0);
00164 p(1) = fm_vnl(2,1);
00165 p(2) = fm_vnl(2,2);
00166 p(3) = fm_vnl(1,2);
00167 p(4) = fm_vnl(0,2);
00168 double norm = vcl_sqrt( p(0)*p(0)+p(1)*p(1) );
00169 p=p/norm;
00170 }
00171
00172
00173
00174 void
00175 rrel_fm_affine_problem::params_to_fm(
00176 const vnl_vector<double>& p,
00177 vpgl_affine_fundamental_matrix<double>& fm ) const
00178 {
00179 fm.set_from_params( p(0), p(1), p(2), p(3), p(4) );
00180 }
00181
00182
00183
00184 bool
00185 rrel_fm_affine_problem::weighted_least_squares_fit(
00186 vnl_vector<double>& ,
00187 vnl_matrix<double>& ,
00188 const vcl_vector<double>* ) const
00189 {
00190 vcl_cerr << "rrel_fm_affine_problem::weighted_least_squares_fit was called, but is not implemented.\n";
00191 return false;
00192 }
00193
00194
00195 #endif // vpgl_fm_compute_affine_ransac_cxx_