00001
00002 #include "rgrl_initializer_ran_sam.h"
00003
00004
00005
00006
00007
00008 #include <vcl_cmath.h>
00009 #include <vcl_cassert.h>
00010
00011 #include "rgrl_match_set.h"
00012 #include "rgrl_estimator.h"
00013 #include "rgrl_scale_estimator.h"
00014 #include "rgrl_scale.h"
00015 #include "rgrl_trans_affine.h"
00016 #include "rgrl_view.h"
00017 #include "rgrl_util.h"
00018
00019 #include <vnl/vnl_random.h>
00020
00021 static const unsigned verbose_ = 0;
00022
00023
00024 static vnl_random global_generator_;
00025
00026
00027
00028 typedef rgrl_match_set::from_iterator FIter;
00029 typedef FIter::to_iterator TIter;
00030
00031 rgrl_initializer_ran_sam::
00032 rgrl_initializer_ran_sam( )
00033 : generate_all_(false),
00034 generator_( &global_generator_ ),
00035 own_generator_( false ),
00036 xform_(0), scale_(0),
00037 samples_to_take_(0)
00038 {
00039 set_sampling_params();
00040 }
00041
00042 rgrl_initializer_ran_sam::
00043 rgrl_initializer_ran_sam( int seed )
00044 : generate_all_(false),
00045 generator_( new vnl_random( seed ) ),
00046 own_generator_( true ),
00047 xform_(0), scale_(0),
00048 samples_to_take_(0)
00049 {
00050 set_sampling_params();
00051 }
00052
00053 rgrl_initializer_ran_sam::
00054 ~rgrl_initializer_ran_sam()
00055 {
00056 if ( own_generator_ )
00057 delete generator_;
00058 }
00059
00060 void
00061 rgrl_initializer_ran_sam::
00062 set_gen_all_samples()
00063 {
00064 generate_all_ = true;
00065 }
00066
00067 void
00068 rgrl_initializer_ran_sam::
00069 set_sampling_params( double max_outlier_frac,
00070 double desired_prob_good,
00071 unsigned int max_populations_expected,
00072 unsigned int min_samples )
00073 {
00074 data_set_ = false;
00075 generate_all_ = false;
00076 max_outlier_frac_ = max_outlier_frac;
00077 desired_prob_good_ = desired_prob_good;
00078 max_populations_expected_ = max_populations_expected;
00079 min_samples_ = min_samples;
00080 }
00081
00082 void
00083 rgrl_initializer_ran_sam::
00084 set_data(rgrl_match_set_sptr init_match_set,
00085 rgrl_scale_estimator_unwgted_sptr scale_est,
00086 rgrl_view_sptr prior_view,
00087 bool should_estimate_global_region)
00088 {
00089 match_set_ = init_match_set;
00090 transform_estiamtor_ = prior_view->xform_estimator();
00091 scale_estimator_ = scale_est;
00092 init_view_ = prior_view;
00093 data_set_ = true;
00094 called_before_ = false;
00095 should_estimate_global_region_ = should_estimate_global_region;
00096 }
00097
00098 void
00099 rgrl_initializer_ran_sam::
00100 set_data(rgrl_match_set_sptr init_match_set,
00101 rgrl_scale_estimator_unwgted_sptr scale_est,
00102 rgrl_mask_sptr const& from_image_roi,
00103 rgrl_mask_sptr const& to_image_roi,
00104 rgrl_mask_box const& initial_from_image_roi,
00105 rgrl_estimator_sptr xform_estimator,
00106 unsigned initial_resolution,
00107 bool should_estimate_global_region)
00108 {
00109 rgrl_mask_box global_region( from_image_roi->bounding_box() );
00110 rgrl_view_sptr prior_view = new rgrl_view( from_image_roi, to_image_roi,
00111 initial_from_image_roi,
00112 global_region, xform_estimator,
00113 0, initial_resolution );
00114 set_data( init_match_set, scale_est, prior_view, should_estimate_global_region );
00115 }
00116
00117 void
00118 rgrl_initializer_ran_sam::
00119 set_data(rgrl_match_set_sptr init_match_set,
00120 rgrl_scale_estimator_unwgted_sptr scale_est,
00121 rgrl_mask_sptr const& from_image_roi,
00122 rgrl_mask_sptr const& to_image_roi,
00123 rgrl_estimator_sptr xform_estimator,
00124 unsigned initial_resolution )
00125 {
00126 rgrl_mask_box global_region( from_image_roi->bounding_box() );
00127 rgrl_view_sptr prior_view = new rgrl_view( from_image_roi, to_image_roi,
00128 global_region, global_region,
00129 xform_estimator, 0,
00130 initial_resolution );
00131 set_data( init_match_set, scale_est, prior_view, false );
00132 }
00133
00134 void
00135 rgrl_initializer_ran_sam::
00136 set_data(rgrl_match_set_sptr init_match_set,
00137 rgrl_scale_estimator_unwgted_sptr scale_est,
00138 rgrl_mask_sptr const& from_image_roi,
00139 rgrl_estimator_sptr xform_estimator,
00140 unsigned initial_resolution )
00141 {
00142 rgrl_mask_box global_region( from_image_roi->bounding_box() );
00143 rgrl_view_sptr prior_view = new rgrl_view( from_image_roi, from_image_roi,
00144 global_region, global_region,
00145 xform_estimator, 0,
00146 initial_resolution );
00147 set_data( init_match_set, scale_est, prior_view, false );
00148 }
00149
00150 bool
00151 rgrl_initializer_ran_sam::
00152 next_initial( rgrl_view_sptr & view,
00153 rgrl_scale_sptr & prior_scale)
00154 {
00155 if ( called_before_ ) return false;
00156
00157 if (!estimate()) return false;
00158
00159 int dim = init_view_->from_image_roi()->x0().size();
00160 rgrl_mask_box global_region( dim );
00161
00162 if ( should_estimate_global_region_ )
00163 global_region =
00164 rgrl_util_estimate_global_region(init_view_->from_image_roi(),
00165 init_view_->to_image_roi(),
00166 init_view_->global_region(),
00167 *xform_);
00168 else {
00169 global_region.set_x0( init_view_->from_image_roi()->x0() );
00170 global_region.set_x1( init_view_->from_image_roi()->x1() );
00171 }
00172
00173 view = new rgrl_view(init_view_->from_image_roi(), init_view_->to_image_roi(),
00174 init_view_->region(), global_region,
00175 init_view_-> xform_estimator(),
00176 xform_,
00177 init_view_->resolution());
00178 prior_scale = scale_;
00179
00180 called_before_ = true;
00181
00182 return true;
00183 }
00184
00185 bool
00186 rgrl_initializer_ran_sam::
00187 estimate()
00188 {
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 unsigned int total_num_matches = 0;
00199 for ( FIter fi = match_set_->from_begin(); fi != match_set_->from_end(); ++fi ) {
00200 total_num_matches += fi.size();
00201 }
00202 this->calc_num_samples( total_num_matches );
00203
00204 DebugMacro_abv( 1 , "Samples = " << samples_to_take_ <<'\n' );
00205
00206 unsigned int points_per = (int)vcl_floor((double)transform_estiamtor_->param_dof()/match_set_->num_constraints_per_match());
00207 vcl_vector<int> point_indices( points_per );
00208 rgrl_trans_affine dummy_trans(3);
00209 rgrl_scale_sptr dummy_scale;
00210 bool scale_set=false;
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 for ( unsigned int s = 0; s<samples_to_take_; ++s )
00223 {
00224 this->next_sample( s, total_num_matches, point_indices, points_per );
00225 rgrl_match_set_sptr
00226 sub_match_set = this->get_matches(point_indices,total_num_matches );
00227 if (this->debug_flag() > 2) this->trace_sample( point_indices );
00228
00229 rgrl_transformation_sptr
00230 new_xform = transform_estiamtor_->estimate( sub_match_set, dummy_trans );
00231 if ( new_xform )
00232 {
00233 match_set_->remap_from_features(*new_xform);
00234 rgrl_scale_sptr
00235 new_scale = scale_estimator_->estimate_unweighted(*match_set_, dummy_scale);
00236
00237 if ( !scale_set || (new_scale->has_geometric_scale() &&
00238 new_scale->geometric_scale() < scale_->geometric_scale()) ) {
00239 scale_ = new_scale;
00240 xform_ = new_xform;
00241 scale_set = true;
00242 }
00243 }
00244 else DebugMacro_abv(1, "No fit to sample.\n");
00245 }
00246
00247 if ( ! scale_set ) {
00248 return false;
00249 }
00250
00251 DebugMacro_abv(1,"Final geometric scale = "<<scale_->geometric_scale()<<'\n');
00252
00253 return true;
00254 }
00255
00256
00257
00258 void
00259 rgrl_initializer_ran_sam::
00260 calc_num_samples( unsigned int num_matches )
00261 {
00262 if ( generate_all_ ) {
00263
00264
00265
00266 unsigned long numer=1;
00267 unsigned long denom=1;
00268 unsigned int n=num_matches;
00269 unsigned int k=(int)vcl_floor((double)transform_estiamtor_->param_dof()/match_set_->num_constraints_per_match());
00270 for ( ; k>0; --k, --n ) {
00271 numer *= n;
00272 denom *= k;
00273 }
00274 samples_to_take_ = (unsigned int)( numer / denom );
00275 }
00276 else {
00277
00278
00279
00280
00281 int num_samples_to_instantiate =
00282 (int)vcl_floor((double)transform_estiamtor_->param_dof()/match_set_->num_constraints_per_match());
00283 unsigned int num_unique_matches = match_set_->from_size();
00284 double prob_pt_inlier = (1 - max_outlier_frac_) * num_unique_matches / double(num_matches);
00285 double prob_pt_good
00286 = max_populations_expected_
00287 * vcl_pow( prob_pt_inlier / max_populations_expected_, num_samples_to_instantiate );
00288 samples_to_take_ = int(vcl_ceil( vcl_log(1.0 - desired_prob_good_) /
00289 vcl_log(1.0 - prob_pt_good) ));
00290 if ( samples_to_take_ < min_samples_ )
00291 samples_to_take_ = min_samples_;
00292 }
00293 }
00294
00295
00296 void
00297 rgrl_initializer_ran_sam::
00298 next_sample( unsigned int taken, unsigned int num_points,
00299 vcl_vector<int>& sample,
00300 unsigned int points_per_sample )
00301 {
00302 assert( sample.size() == points_per_sample );
00303
00304 if ( generate_all_ ) {
00305 if ( taken == 0 ) {
00306 for ( unsigned int i=0; i<points_per_sample; ++i )
00307 sample[i] = i;
00308 }
00309 else if ( taken >= samples_to_take_ )
00310 vcl_cerr << "rrel_ran_sam_search::next_sample -- ERROR: used all samples\n";
00311 else {
00312
00313
00314
00315 unsigned int i=points_per_sample-1;
00316 unsigned int k=num_points-1;
00317 while ( sample[i] == (int)k ) { --i; --k; }
00318 k = ++ sample[i];
00319 for ( ++k, ++i; i<points_per_sample; ++i, ++k )
00320 sample[i]=k;
00321 }
00322 }
00323 else if ( num_points == 1 ) {
00324 sample[0] = 0;
00325 }
00326 else
00327 {
00328 unsigned int k=0, counter=0;
00329 while ( k<points_per_sample )
00330 {
00331 int id = generator_->lrand32( 0, num_points-1 );
00332 if ( id >= int(num_points) ) {
00333 vcl_cerr << "rrel_ran_sam_search::next_sample --- "
00334 << "WARNING: random value out of range\n";
00335 }
00336 else
00337 {
00338 ++counter;
00339 bool different = true;
00340 for ( int i=k-1; i>=0 && different; --i )
00341 different = (id != sample[i]);
00342 if ( different )
00343 sample[k++] = id, counter = 0;
00344 else if (counter > 100)
00345 {
00346 vcl_cerr << "rrel_ran_sam_search::next_sample --- WARNING: "
00347 << "lrand32() generated 100x the same value "<< id
00348 << " from the range [0," << num_points-1 << "]\n";
00349 sample[k++] = id+1;
00350 }
00351 }
00352 }
00353 }
00354 }
00355
00356 rgrl_match_set_sptr
00357 rgrl_initializer_ran_sam::
00358 get_matches(const vcl_vector<int>& point_indices, unsigned int total_num_matches)
00359 {
00360 rgrl_match_set_sptr
00361 sub_match_set = new rgrl_match_set( match_set_->from_feature_type(), match_set_->to_feature_type() );
00362
00363 if ( total_num_matches == match_set_->from_size() ) {
00364 for (unsigned int i = 0; i<point_indices.size(); ++i) {
00365 FIter fi = match_set_->from_begin() + point_indices[i];
00366 TIter ti = fi.begin();
00367 sub_match_set->add_feature_and_match( fi.from_feature(),
00368 fi.mapped_from_feature(),
00369 ti.to_feature() );
00370 }
00371 }
00372 else {
00373 int match_count = 0;
00374 for ( FIter fi = match_set_->from_begin(); fi != match_set_->from_end(); ++fi ) {
00375 for (unsigned int i = 0; i<point_indices.size(); ++i) {
00376 if ( match_count <= point_indices[i] && match_count + (int)fi.size() > point_indices[i]) {
00377 unsigned int offset = point_indices[i] - match_count;
00378 TIter ti = fi.begin() + offset;
00379 sub_match_set->add_feature_and_match( fi.from_feature(),
00380 fi.mapped_from_feature(),
00381 ti.to_feature() );
00382 }
00383 }
00384 match_count += fi.size();
00385 }
00386 }
00387
00388 return sub_match_set;
00389 }
00390
00391 void
00392 rgrl_initializer_ran_sam::
00393 trace_sample( const vcl_vector<int>& indices ) const
00394 {
00395 vcl_cout << "\nNew sample: ";
00396 for ( unsigned int i=0; i<indices.size(); ++i)
00397 vcl_cout << ' ' << indices[i];
00398 vcl_cout << vcl_endl;
00399 }