Go to the documentation of this file.00001 #include "rgrl_est_translation.h"
00002
00003
00004
00005
00006
00007 #include <vcl_cassert.h>
00008 #include <vnl/algo/vnl_svd.h>
00009 #include "rgrl_trans_translation.h"
00010 #include "rgrl_match_set.h"
00011
00012 rgrl_est_translation::
00013 rgrl_est_translation( unsigned int dimension )
00014 {
00015
00016
00017 unsigned int param_dof = dimension;
00018
00019
00020
00021 rgrl_estimator::set_param_dof( param_dof );
00022 }
00023
00024 rgrl_transformation_sptr
00025 rgrl_est_translation::
00026 estimate( rgrl_set_of<rgrl_match_set_sptr> const& matches,
00027 rgrl_transformation const& ) const
00028 {
00029
00030
00031 typedef rgrl_match_set::const_from_iterator FIter;
00032 typedef FIter::to_iterator TIter;
00033
00034
00035
00036
00037 unsigned ms = 0;
00038 while ( ms < matches.size() &&
00039 matches[ms]->from_begin() == matches[ms]->from_end() )
00040 ++ms;
00041 if ( ms == matches.size() ) {
00042 DebugMacro(0, "No data!\n");
00043 return 0;
00044 }
00045 const unsigned int m = matches[ms]->from_begin().from_feature()->location().size();
00046 assert ( m>=1 );
00047
00048
00049
00050
00051 vnl_matrix<double> XtWX( m, m );
00052 vnl_vector<double> XtWy( m );
00053 XtWX.fill( 0.0 );
00054 XtWy.fill( 0.0 );
00055
00056
00057
00058
00059 vnl_vector<double> from_centre( m, 0.0 );
00060 vnl_vector<double> to_centre( m, 0.0 );
00061 vnl_vector<double> from_pt( m );
00062 vnl_vector<double> to_pt( m );
00063 vnl_vector<double> Bq (m);
00064 vnl_matrix<double> wgtB( m, m );
00065 double sum_wgt = 0.0;
00066 unsigned count=0;
00067 for ( unsigned ms=0; ms < matches.size(); ++ms ) {
00068 rgrl_match_set const& match_set = *matches[ms];
00069 for ( FIter fi = match_set.from_begin(); fi != match_set.from_end(); ++fi ) {
00070 for ( TIter ti = fi.begin(); ti != fi.end(); ++ti ) {
00071 double const wgt = ti.cumulative_weight();
00072 from_pt = fi.from_feature()->location();
00073 from_pt *= wgt;
00074 from_centre += from_pt;
00075 to_pt = ti.to_feature()->location();
00076 to_pt *= wgt;
00077 to_centre += to_pt;
00078 sum_wgt += wgt;
00079 }
00080 }
00081 }
00082
00083
00084 if( sum_wgt < 1e-13 ) {
00085 return 0;
00086 }
00087
00088 from_centre /= sum_wgt;
00089 to_centre /= sum_wgt;
00090
00091
00092
00093
00094 for ( unsigned ms=0; ms < matches.size(); ++ms ) {
00095 rgrl_match_set const& match_set = *matches[ms];
00096 for ( FIter fi = match_set.from_begin(); fi != match_set.from_end(); ++fi ) {
00097 for ( TIter ti = fi.begin(); ti != fi.end(); ++ti ) {
00098 from_pt = fi.from_feature()->location();
00099 from_pt -= from_centre;
00100 to_pt = ti.to_feature()->location();
00101 to_pt -= to_centre;
00102 vnl_matrix<double> const& B = ti.to_feature()->error_projector();
00103 double const wgt = ti.cumulative_weight();
00104
00105 assert ( from_pt.size() == m );
00106 assert ( to_pt.size() == m );
00107 assert ( B.cols() == m && B.rows() == m );
00108 ++count;
00109
00110
00111 wgtB = B;
00112 wgtB *= wgt;
00113 XtWX += wgtB;
00114
00115
00116 Bq = to_pt.pre_multiply( B );
00117 for ( unsigned i = 0; i<m; ++i)
00118 XtWy[i] += wgt * Bq[i];
00119 }
00120 }
00121 }
00122
00123
00124
00125
00126 vnl_svd<double> svd( XtWX );
00127
00128
00129
00130 svd.zero_out_relative();
00131
00132
00133 if ( (unsigned)svd.rank() < m ) {
00134 DebugMacro(1, "rank ("<<svd.rank()<<") < "<<m<<"; no solution." );
00135 DebugMacro_abv(1," (used " << count << " correspondences)\n" );
00136
00137 return 0;
00138 }
00139
00140
00141
00142 vnl_matrix<double> covar = svd.inverse();
00143 XtWy.pre_multiply( covar );
00144
00145 vnl_vector<double> trans = XtWy;
00146
00147 DebugMacro(1,"T =\n" << trans-from_centre+to_centre << '\n' );
00148
00149 return new rgrl_trans_translation( trans, covar, from_centre, to_centre );
00150 }
00151
00152
00153 rgrl_transformation_sptr
00154 rgrl_est_translation::
00155 estimate( rgrl_match_set_sptr matches,
00156 rgrl_transformation const& cur_transform ) const
00157 {
00158
00159 return rgrl_estimator::estimate( matches, cur_transform );
00160 }
00161
00162 const vcl_type_info&
00163 rgrl_est_translation::
00164 transformation_type() const
00165 {
00166 return rgrl_trans_translation::type_id();
00167 }