Go to the documentation of this file.00001
00002
00003
00004
00005 #include "rgrl_scale_est_closest.h"
00006
00007 #include <rrel/rrel_objective.h>
00008 #include <vnl/vnl_math.h>
00009
00010 #include "rgrl_scale.h"
00011 #include "rgrl_match_set.h"
00012 #include "rgrl_util.h"
00013
00014 #include <vcl_iostream.h>
00015 #include <vcl_cassert.h>
00016
00017 rgrl_scale_est_closest::
00018 rgrl_scale_est_closest( vcl_auto_ptr<rrel_objective> obj,
00019 bool do_signature_scale )
00020 : do_signature_scale_( do_signature_scale ),
00021 obj_( obj )
00022 {
00023 assert( obj_->can_estimate_scale() );
00024 }
00025
00026
00027 rgrl_scale_est_closest::
00028 ~rgrl_scale_est_closest()
00029 {
00030 }
00031
00032
00033 rgrl_scale_sptr
00034 rgrl_scale_est_closest::
00035 estimate_unweighted( rgrl_match_set const& match_set,
00036 rgrl_scale_sptr const& ,
00037 bool penalize_scaling ) const
00038 {
00039 rgrl_scale_sptr scales = new rgrl_scale;
00040
00041 double scale = -1.0;
00042 vnl_matrix<double> inv_covar;
00043
00044 if( compute_geometric_scale( scale, match_set, penalize_scaling ) )
00045 scales->set_geometric_scale( scale );
00046
00047 if ( do_signature_scale_ && compute_signature_inv_covar( inv_covar, match_set ) ) {
00048 scales->set_signature_inv_covar( inv_covar );
00049 }
00050
00051 return scales;
00052 }
00053
00054
00055 bool
00056 rgrl_scale_est_closest::
00057 compute_geometric_scale( double& return_scale,
00058 rgrl_match_set const& match_set,
00059 bool penalize_scaling ) const
00060 {
00061 typedef rgrl_match_set::const_from_iterator from_iter;
00062 typedef from_iter::to_iterator to_iter;
00063
00064 double scaling = 1;
00065 if ( penalize_scaling ) {
00066
00067 scaling = rgrl_util_geometric_error_scaling( match_set );
00068 }
00069
00070 vcl_vector<double> error_distances;
00071 error_distances.reserve( match_set.from_size() );
00072 DebugMacro(1, "\n");
00073
00074 for ( from_iter fitr = match_set.from_begin(); fitr != match_set.from_end(); ++fitr ) {
00075
00076
00077 if ( fitr.empty() ) {
00078 DebugMacro_abv(1," no matched points for from: "<< fitr.from_feature()->location()<< ", set its error distances = 1.0e30\n");
00079 error_distances.push_back( 1.0e30 );
00080 } else {
00081 to_iter titr = fitr.begin();
00082
00083 rgrl_feature_sptr mapped_from = fitr.mapped_from_feature();
00084 double min_distance = titr.to_feature()->geometric_error( *mapped_from );
00085
00086 for ( ++titr; titr != fitr.end(); ++titr ) {
00087 double distance = titr.to_feature()->geometric_error( *mapped_from );
00088 if ( distance < min_distance ) {
00089 min_distance = distance;
00090 }
00091 }
00092 error_distances.push_back( min_distance );
00093 }
00094 }
00095
00096 #if 0 // commented out
00097 vcl_cout << " error_distance :\n" << vcl_endl;
00098 unsigned zeros = 0;
00099 for ( unsigned i = 0; i < error_distances.size(); ++i ) {
00100 if ( error_distances[ i ] == 0 )
00101 ++zeros;
00102 vcl_cout << error_distances[ i ] << vcl_endl;
00103 }
00104 vcl_cout << " number of zers : " << zeros << " out of " << error_distances.size() << vcl_endl;
00105 #endif // 0
00106
00107
00108 if( error_distances.empty() )
00109 return false;
00110
00111 const double epsilon = 1e-16;
00112 return_scale = scaling * vnl_math_max( obj_->scale( error_distances.begin(), error_distances.end() ), epsilon );
00113
00114
00115 if( !vnl_math_isfinite( return_scale ) )
00116 return false;
00117
00118
00119 return true;
00120 }
00121
00122 bool
00123 rgrl_scale_est_closest::
00124 compute_signature_inv_covar( vnl_matrix<double>& inv_covar, rgrl_match_set const& match_set ) const
00125 {
00126 if( !match_set.from_size() ) return false;
00127
00128
00129
00130
00131
00132
00133 typedef rgrl_match_set::const_from_iterator from_iter;
00134 typedef from_iter::to_iterator to_iter;
00135
00136 from_iter fitr = match_set.from_begin();
00137 const unsigned nrows = fitr.from_feature()->signature_error_dimension( match_set.to_feature_type() );
00138
00139
00140 if( !nrows ) return false;
00141
00142 vcl_vector< vcl_vector<double> > all_errors( nrows );
00143 bool success = true;
00144
00145 for ( ; fitr != match_set.from_end(); ++fitr ) {
00146
00147
00148 if ( fitr.empty() ) {
00149 for ( unsigned r=0; r<nrows; ++r ) {
00150 all_errors[r].push_back( 1.0e30 );
00151 }
00152 } else {
00153 to_iter titr = fitr.begin();
00154 to_iter best_titr = titr;
00155
00156 rgrl_feature_sptr mapped_from = fitr.mapped_from_feature();
00157 double min_distance = titr.to_feature()->geometric_error( *mapped_from );
00158
00159 for ( ++titr; titr != fitr.end(); ++titr ) {
00160 double distance = titr.to_feature()->geometric_error( *mapped_from );
00161 if ( distance < min_distance ) {
00162 min_distance = distance;
00163 best_titr = titr;
00164 }
00165 }
00166
00167 vnl_vector<double> signature_error = best_titr.to_feature()->signature_error_vector( *mapped_from );
00168 for ( unsigned r = 0; r < nrows; ++r ) {
00169 all_errors[r].push_back( signature_error[r] );
00170 }
00171 }
00172 }
00173
00174 inv_covar.set_size( nrows, nrows );
00175 inv_covar.fill( 0.0 );
00176
00177 for ( unsigned r = 0; r < nrows&&success; ++r ) {
00178
00179 if( all_errors[r].empty() ) {
00180 success = false;
00181 break;
00182 }
00183
00184 const double std = obj_->scale( all_errors[r].begin(), all_errors[r].end() );
00185 success = success && vnl_math_isfinite( std );
00186 if( std < 1e-10 )
00187 inv_covar(r,r) = 0.0;
00188 else
00189 inv_covar(r,r) = 1 / vnl_math_sqr( std );
00190 }
00191
00192 return success;
00193 }
00194
00195
00196 rgrl_scale_sptr
00197 rgrl_scale_est_closest::
00198 estimate_weighted( rgrl_match_set const& match_set,
00199 rgrl_scale_sptr const& scales,
00200 bool ,
00201 bool penalize_scaling ) const
00202 {
00203 return estimate_unweighted( match_set, scales, penalize_scaling );
00204 }