Go to the documentation of this file.00001 #include "rgrl_weighter_m_est.h"
00002
00003
00004
00005
00006
00007 #include <vcl_cmath.h>
00008 #include <vcl_cassert.h>
00009 #include <vnl/vnl_matrix.h>
00010 #include <vnl/vnl_math.h>
00011 #include <rrel/rrel_m_est_obj.h>
00012
00013 #include "rgrl_match_set.h"
00014 #include "rgrl_scale.h"
00015 #include "rgrl_transformation.h"
00016
00017 rgrl_weighter_m_est::
00018 rgrl_weighter_m_est( vcl_auto_ptr<rrel_m_est_obj> m_est,
00019 bool use_signature_error,
00020 bool use_precomputed_signature_wgt )
00021 : m_est_( m_est ),
00022 use_signature_error_( use_signature_error ),
00023 signature_precomputed_( use_precomputed_signature_wgt ),
00024 weight_more_on_distinct_match_( true )
00025 {
00026 }
00027
00028
00029 rgrl_weighter_m_est::
00030 ~rgrl_weighter_m_est()
00031 {
00032 }
00033
00034
00035 void
00036 rgrl_weighter_m_est::
00037 compute_weights( rgrl_scale const& scales,
00038 rgrl_match_set& match_set ) const
00039 {
00040
00041
00042
00043 vnl_matrix<double> signature_inv_covar;
00044 if ( use_signature_error_ && !signature_precomputed_ ) {
00045 assert ( scales.has_signature_inv_covar() );
00046 signature_inv_covar = scales.signature_inv_covar();
00047 }
00048
00049
00050 assert ( scales.has_geometric_scale() );
00051 double geometric_scale = scales.geometric_scale();
00052
00053 typedef rgrl_match_set::from_iterator from_iter;
00054 typedef from_iter::to_iterator to_iter;
00055
00056 DebugMacro(1,'\n');
00057 DebugMacro_abv(1, "Matched points : from\t to\t geo_err\t geo_wgt\t cum_wgt:\n" );
00058
00059
00060 for ( from_iter fitr = match_set.from_begin();
00061 fitr != match_set.from_end(); ++fitr ) {
00062
00063 DebugMacro_abv(1, fitr.from_feature()->location() << '\t');
00064 if ( fitr.empty() ) DebugMacro_abv(2, '\n' );
00065
00066 if ( fitr.size() == 0 ) continue;
00067
00068 double sum_weights = 0;
00069 rgrl_feature_sptr mapped_from = fitr.mapped_from_feature();
00070
00071 for ( to_iter titr = fitr.begin(); titr != fitr.end(); ++titr )
00072 {
00073 DebugMacro_abv( 1, titr.to_feature()->location() << "\t " );
00074
00075
00076 rgrl_feature_sptr to_feature = titr.to_feature();
00077
00078 double geometric_err = to_feature->geometric_error( *mapped_from );
00079 double geometric_wgt = m_est_->wgt( geometric_err, geometric_scale );
00080
00081 DebugMacro_abv(1, geometric_err << "\t " << geometric_wgt << "\t " );
00082
00083 double signature_wgt = 1.0;
00084 if ( signature_precomputed_ ) {
00085 signature_wgt = titr . signature_weight( );
00086 }
00087 else if ( use_signature_error_ ) {
00088 vnl_vector<double> error_vector = to_feature->signature_error_vector( *mapped_from );
00089 assert ( error_vector.size() > 0 &&
00090 error_vector.size() == signature_inv_covar.rows() &&
00091 error_vector.size() == signature_inv_covar.cols());
00092 double signature_err = vcl_sqrt( dot_product( error_vector * signature_inv_covar, error_vector ) );
00093
00094
00095 signature_wgt = m_est_->wgt( signature_err );
00096 }
00097
00098 double cumul_wgt = geometric_wgt * signature_wgt;
00099
00100 DebugMacro_abv(1, cumul_wgt << vcl_endl );
00101
00102 titr.set_geometric_weight( geometric_wgt );
00103 if ( !signature_precomputed_ ) titr.set_signature_weight( signature_wgt );
00104 titr.set_cumulative_weight( cumul_wgt );
00105 sum_weights += cumul_wgt;
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 if ( sum_weights > 1e-16 ) {
00117 if( weight_more_on_distinct_match_ )
00118 for ( to_iter titr = fitr.begin(); titr != fitr.end(); ++titr ) {
00119 double wgt = titr.cumulative_weight();
00120 titr.set_cumulative_weight( wgt*wgt / sum_weights );
00121 }
00122 else
00123 for ( to_iter titr = fitr.begin(); titr != fitr.end(); ++titr ) {
00124 double wgt = titr.cumulative_weight();
00125 titr.set_cumulative_weight( wgt / sum_weights );
00126 }
00127 }
00128 }
00129 }
00130
00131 double
00132 rgrl_weighter_m_est::
00133 aux_sum_weighted_residuals( rgrl_scale const& scale,
00134 rgrl_match_set& match_set,
00135 rgrl_transformation const& xform )
00136 {
00137 typedef rgrl_match_set::from_iterator from_iter;
00138 typedef from_iter::to_iterator to_iter;
00139
00140 if ( match_set.from_size() > 0) {
00141 match_set.remap_from_features( xform );
00142 compute_weights( scale, match_set );
00143 }
00144
00145 double weighted_sum = 0;
00146
00147
00148
00149
00150 for ( from_iter fitr = match_set.from_begin(); fitr != match_set.from_end(); ++fitr ){
00151 if ( fitr.size() == 0 ) continue;
00152
00153 rgrl_feature_sptr mapped_from = fitr.mapped_from_feature();
00154 for ( to_iter titr = fitr.begin(); titr != fitr.end(); ++titr ) {
00155
00156 rgrl_feature_sptr to_feature = titr.to_feature();
00157 double geometric_err = to_feature->geometric_error( *mapped_from );
00158
00159 weighted_sum += vnl_math_sqr(geometric_err) * titr.geometric_weight();
00160 }
00161 }
00162
00163 return weighted_sum;
00164 }
00165
00166
00167
00168
00169
00170 double
00171 rgrl_weighter_m_est::
00172 aux_sum_rho_values( rgrl_scale const& scale,
00173 rgrl_match_set& match_set,
00174 rgrl_transformation const& xform )
00175 {
00176 typedef rgrl_match_set::from_iterator from_iter;
00177 typedef from_iter::to_iterator to_iter;
00178
00179 if ( match_set.from_size() == 0 ) return 0;
00180
00181 double sum_rho = 0;
00182
00183 for ( from_iter fitr = match_set.from_begin(); fitr != match_set.from_end(); ++fitr ){
00184 if ( fitr.size() == 0 ) continue;
00185
00186 rgrl_feature_sptr mapped_from = fitr.from_feature()->transform( xform );
00187 to_iter titr = fitr.begin();
00188 double min_val = titr.to_feature()->geometric_error( *mapped_from );
00189
00190 for ( ++titr; titr != fitr.end(); ++titr ) {
00191
00192 rgrl_feature_sptr to_feature = titr.to_feature();
00193 double geometric_err = to_feature->geometric_error( *mapped_from );
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 if( min_val > geometric_err )
00204 min_val = geometric_err;
00205 }
00206
00207 sum_rho += m_est_->rho(min_val, scale.geometric_scale());
00208 }
00209
00210 return sum_rho;
00211 }
00212
00213 double
00214 rgrl_weighter_m_est::
00215 aux_neg_log_likelihood( rgrl_scale const& scale,
00216 rgrl_match_set& match_set,
00217 rgrl_transformation const& xform )
00218 {
00219 typedef rgrl_match_set::from_iterator from_iter;
00220 typedef from_iter::to_iterator to_iter;
00221
00222 int n = 0;
00223
00224 for ( from_iter fitr = match_set.from_begin(); fitr != match_set.from_end(); ++fitr )
00225 if( fitr.size() > 0 ) {
00226
00227 n ++;
00228 }
00229
00230 double sum_rho_values = aux_sum_rho_values(scale, match_set, xform);
00231 const double geometric_scale = scale.geometric_scale();
00232
00233 return n*vcl_log(geometric_scale) + sum_rho_values;
00234 }
00235
00236 double
00237 rgrl_weighter_m_est::
00238 aux_avg_neg_log_likelihood( rgrl_scale const& scale,
00239 rgrl_match_set& match_set,
00240 rgrl_transformation const& xform )
00241 {
00242 typedef rgrl_match_set::from_iterator from_iter;
00243 typedef from_iter::to_iterator to_iter;
00244
00245 int n = 0;
00246
00247 for ( from_iter fitr = match_set.from_begin(); fitr != match_set.from_end(); ++fitr )
00248 if( fitr.size() > 0 ) {
00249
00250 n ++;
00251 }
00252
00253 if( !n )
00254 return 0;
00255
00256 double sum_rho_values = aux_sum_rho_values(scale, match_set, xform);
00257 const double geometric_scale = scale.geometric_scale();
00258
00259 return vcl_log(geometric_scale) + sum_rho_values/double(n);
00260 }