contrib/rpl/rrel/rrel_shift2d_est.cxx
Go to the documentation of this file.
00001 #include "rrel_shift2d_est.h"
00002 
00003 #include <vgl/vgl_homg_point_2d.h>
00004 #include <vnl/vnl_vector.h>
00005 #include <vnl/vnl_math.h>
00006 
00007 #include <vcl_cassert.h>
00008 #include <vcl_cmath.h>
00009 
00010 rrel_shift2d_est::rrel_shift2d_est(
00011     const vcl_vector< vgl_homg_point_2d<double> > & from_pts,
00012     const vcl_vector< vgl_homg_point_2d<double> > & to_pts )
00013     : rrel_estimation_problem( 2 /*dof*/, 1 /*points to instantiate*/ )
00014 {
00015   assert( from_pts.size() == to_pts.size() );
00016   vnl_vector< double > p(3), q(3);
00017 
00018   for ( unsigned int i=0; i<from_pts.size(); ++i ) {
00019     p[0] = from_pts[i].x();
00020     p[1] = from_pts[i].y();
00021     p[2] = from_pts[i].w();
00022     assert( p[2] != 0 );
00023     from_pts_.push_back( p );
00024     q[0] = to_pts[i].x();
00025     q[1] = to_pts[i].y();
00026     q[2] = to_pts[i].w();
00027     assert( q[2] != 0 );
00028     to_pts_.push_back( q );
00029   }
00030   compute_del_pts ();
00031 }
00032 
00033 rrel_shift2d_est::rrel_shift2d_est(
00034     const vcl_vector< vnl_vector<double> > & from_pts,
00035     const vcl_vector< vnl_vector<double> > & to_pts )
00036     : rrel_estimation_problem( 2 /*dof*/, 1 /*points to instantiate*/ ),
00037       from_pts_( from_pts ), to_pts_( to_pts )
00038 {
00039   assert( from_pts_.size() == to_pts_.size() );
00040   for ( unsigned int i=0; i<from_pts_.size(); ++i ) {
00041     assert( from_pts_[ i ][ 2 ] != 0 );
00042     assert( to_pts_[ i ][ 2 ] != 0 );
00043   }
00044   compute_del_pts ();
00045 }
00046 
00047 rrel_shift2d_est::~rrel_shift2d_est()
00048 {
00049 }
00050 
00051 unsigned int
00052 rrel_shift2d_est::num_samples( ) const
00053 {
00054   return from_pts_.size();
00055 }
00056 
00057 bool
00058 rrel_shift2d_est::fit_from_minimal_set(
00059     const vcl_vector<int>& point_indices,
00060     vnl_vector<double>& params ) const
00061 {
00062   assert( point_indices.size() == 1 );
00063   int loc = point_indices[ 0 ];
00064   params = del_pts_[loc];
00065   return true;
00066 }
00067 
00068 void
00069 rrel_shift2d_est::compute_residuals(
00070     const vnl_vector<double>& params,
00071     vcl_vector<double>& residuals ) const
00072 {
00073   assert (2 == params.size() );
00074   if ( residuals.size() != from_pts_.size() )
00075       residuals.resize( from_pts_.size() );
00076 
00077   for (unsigned i=0; i<from_pts_.size(); i++) {
00078       double del_x = del_pts_[i][0] - params[0];
00079       double del_y = del_pts_[i][1] - params[1];
00080       residuals[i] = vcl_sqrt( vnl_math_sqr(del_x) + vnl_math_sqr(del_y) );
00081   }
00082 }
00083 
00084 bool
00085 rrel_shift2d_est::weighted_least_squares_fit(
00086     vnl_vector<double>& params,
00087     vnl_matrix<double>& /* norm_covar */,
00088     const vcl_vector<double>* weights ) const
00089 {
00090   const vcl_vector<double> * w;
00091   if ( weights )
00092     w = weights;
00093   else
00094     w = new vcl_vector<double>( from_pts_.size(), 1 );
00095 
00096   params.set_size(2);
00097   double x_del_tot = 0.0;
00098   double y_del_tot = 0.0;
00099   double weight_tot = 0.0;
00100 
00101   for (unsigned i=0; i<from_pts_.size(); i++) {
00102       x_del_tot += del_pts_[i][0] * (*w)[i];
00103       y_del_tot += del_pts_[i][1] * (*w)[i];
00104       weight_tot += (*w)[i];
00105   }
00106 
00107   params[0] = x_del_tot / weight_tot;
00108   params[1] = y_del_tot / weight_tot;
00109 
00110   if ( !weights )
00111     delete w;
00112 
00113   return true;
00114 }
00115 
00116 void
00117 rrel_shift2d_est::compute_del_pts()
00118 {
00119   assert (0 == del_pts_.size());
00120 
00121   for (unsigned i=0; i<from_pts_.size(); i++) {
00122       assert (0.0 != from_pts_[i][2]);
00123       assert (0.0 != to_pts_[i][2]);
00124       vnl_vector< double > del (2);
00125       del[0] = to_pts_[i][0] / to_pts_[i][2]
00126              - from_pts_[i][0] / from_pts_[i][2];
00127       del[1] = to_pts_[i][1] / to_pts_[i][2]
00128              - from_pts_[i][1] / from_pts_[i][2];
00129       del_pts_.push_back (del);
00130   }
00131 }