00001 #include "rgrl_feature_based_registration.h"
00002
00003
00004 #include "rgrl_initializer.h"
00005 #include "rgrl_convergence_tester.h"
00006 #include "rgrl_converge_status.h"
00007 #include "rgrl_estimator.h"
00008 #include "rgrl_scale_estimator.h"
00009 #include "rgrl_weighter_unit.h"
00010 #include "rgrl_matcher.h"
00011 #include "rgrl_match_set.h"
00012 #include "rgrl_scale_est_null.h"
00013 #include "rgrl_cast.h"
00014 #include "rgrl_data_manager.h"
00015 #include "rgrl_scale.h"
00016 #include "rgrl_util.h"
00017 #include "rgrl_convergence_on_median_error.h"
00018 #include "rgrl_event.h"
00019 #include <vcl_cassert.h>
00020
00021 rgrl_feature_based_registration::
00022 rgrl_feature_based_registration( rgrl_data_manager_sptr data,
00023 rgrl_convergence_tester_sptr conv_tester )
00024 :data_( data ),
00025 conv_tester_( conv_tester ),
00026 num_xforms_tested_( 0 ),
00027 max_icp_iter_(25),
00028 expected_max_geometric_scale_ (0),
00029 expected_min_geometric_scale_ (0),
00030 iterations_for_scale_est_(-1),
00031 should_penalize_scaling_(false),
00032 current_stage_( 0 )
00033 {
00034 }
00035
00036 rgrl_feature_based_registration::
00037 rgrl_feature_based_registration( rgrl_data_manager_sptr data )
00038 :data_( data ),
00039 num_xforms_tested_( 0 ),
00040 max_icp_iter_(25),
00041 expected_max_geometric_scale_ (0),
00042 expected_min_geometric_scale_ (0),
00043 iterations_for_scale_est_(-1),
00044 should_penalize_scaling_(false)
00045 {
00046 double tolerance = 1.0;
00047 conv_tester_ = new rgrl_convergence_on_median_error( tolerance );
00048 }
00049
00050 rgrl_feature_based_registration::
00051 ~rgrl_feature_based_registration()
00052 {
00053 }
00054
00055 void
00056 rgrl_feature_based_registration::
00057 clear_results()
00058 {
00059 num_xforms_tested_ = 0;
00060 best_xform_estimate_ = 0;
00061 best_matches_.clear();
00062 best_scales_.clear();
00063 best_status_ = 0;
00064 }
00065
00066
00067
00068 void
00069 rgrl_feature_based_registration::
00070 run( rgrl_initializer_sptr initializer )
00071 {
00072
00073 this->clear_results();
00074
00075 rgrl_transformation_sptr init_xform_estimate;
00076 rgrl_scale_sptr prior_scale;
00077 rgrl_estimator_sptr init_xform_estimator;
00078 unsigned init_resolution;
00079
00080 rgrl_mask_sptr from_image_roi;
00081 rgrl_mask_sptr to_image_roi;
00082 rgrl_mask_box current_region(0);
00083 rgrl_mask_box global_region(0);
00084
00085 while ( initializer->next_initial( from_image_roi, to_image_roi,
00086 current_region, global_region,
00087 init_xform_estimator, init_xform_estimate,
00088 init_resolution, prior_scale ) ) {
00089 DebugMacro( 1, "Try "<< num_xforms_tested_ << " initial estimate\n" );
00090
00091
00092
00093 this->run( global_region, to_image_roi-> bounding_box(),
00094 init_xform_estimator, init_xform_estimate,
00095 prior_scale, init_resolution );
00096
00097 if ( best_status_ && best_status_->is_good_enough() ) break;
00098
00099 ++num_xforms_tested_;
00100 }
00101 }
00102
00103
00104
00105
00106
00107
00108 void
00109 rgrl_feature_based_registration::
00110 run( rgrl_mask_box from_image_region,
00111 rgrl_mask_box to_image_region,
00112 rgrl_estimator_sptr init_xform_estimator,
00113 rgrl_transformation_sptr initial_xform,
00114 rgrl_scale_sptr prior_scale,
00115 unsigned init_resolution)
00116 {
00117 if ( data_->is_multi_feature() ) {
00118 DebugMacro(1, " Multi-feature Registration:\n");
00119 this->register_multi_feature(from_image_region, to_image_region,
00120 init_xform_estimator, initial_xform,
00121 prior_scale, init_resolution);
00122 }
00123 else {
00124 DebugMacro( 1, " Single-feature Registration:\n" );
00125
00126 this->register_single_feature(from_image_region, to_image_region,
00127 init_xform_estimator,
00128 initial_xform, prior_scale, init_resolution);
00129 }
00130 }
00131
00132
00133
00134
00135 rgrl_transformation_sptr
00136 rgrl_feature_based_registration::
00137 final_transformation() const
00138 {
00139 return best_xform_estimate_;
00140 }
00141
00142
00143 rgrl_set_of<rgrl_scale_sptr> const&
00144 rgrl_feature_based_registration::
00145 final_scales() const
00146 {
00147 return best_scales_;
00148 }
00149
00150 rgrl_scale_sptr
00151 rgrl_feature_based_registration::
00152 final_scale() const
00153 {
00154 assert ( !data_->is_multi_feature() );
00155 return best_scales_[0];
00156 }
00157
00158
00159 rgrl_converge_status_sptr
00160 rgrl_feature_based_registration::
00161 final_status() const
00162 {
00163 return best_status_;
00164 }
00165
00166
00167 rgrl_set_of<rgrl_match_set_sptr> const&
00168 rgrl_feature_based_registration::
00169 final_match_sets() const
00170 {
00171 return best_matches_;
00172 }
00173
00174 rgrl_match_set_sptr
00175 rgrl_feature_based_registration::
00176 final_match_set() const
00177 {
00178 assert ( !data_->is_multi_feature() );
00179 return best_matches_[0];
00180 }
00181
00182
00183 unsigned
00184 rgrl_feature_based_registration::
00185 num_initial_xforms_tested() const
00186 {
00187 return num_xforms_tested_;
00188 }
00189
00190
00191 bool
00192 rgrl_feature_based_registration::
00193 has_final_transformation() const
00194 {
00195 return best_xform_estimate_ != 0;
00196 }
00197
00198
00199 void
00200 rgrl_feature_based_registration::
00201 set_max_icp_iter( unsigned iter )
00202 {
00203 max_icp_iter_ = iter;
00204 }
00205
00206
00207 void
00208 rgrl_feature_based_registration::
00209 set_expected_max_geometric_scale( double scale)
00210 {
00211 expected_max_geometric_scale_ = scale;
00212 }
00213
00214
00215 void
00216 rgrl_feature_based_registration::
00217 set_expected_min_geometric_scale( double scale)
00218 {
00219 expected_min_geometric_scale_ = scale;
00220 }
00221
00222
00223 void
00224 rgrl_feature_based_registration::
00225 set_iterations_for_scale_est( int iter)
00226 {
00227 iterations_for_scale_est_ = iter;
00228 }
00229
00230
00231 void
00232 rgrl_feature_based_registration::
00233 penalize_scaling( bool penalize)
00234 {
00235 should_penalize_scaling_ = penalize;
00236 }
00237
00238
00239
00240 rgrl_set_of<rgrl_match_set_sptr> const&
00241 rgrl_feature_based_registration::
00242 current_match_sets() const
00243 {
00244 return current_match_sets_;
00245 }
00246
00247
00248 rgrl_transformation_sptr
00249 rgrl_feature_based_registration::
00250 current_transformation() const
00251 {
00252 return current_xform_estimate_;
00253 }
00254
00255
00256 unsigned
00257 rgrl_feature_based_registration::
00258 current_stage() const
00259 {
00260 return current_stage_;
00261 }
00262
00263
00264 unsigned
00265 rgrl_feature_based_registration::
00266 iterations_at_current_stage() const
00267 {
00268 return iterations_at_stage_;
00269 }
00270
00271
00272
00273
00274
00275 void
00276 rgrl_feature_based_registration::
00277 register_single_feature( rgrl_mask_box from_image_region,
00278 rgrl_mask_box to_image_region,
00279 rgrl_estimator_sptr initial_xform_estimator,
00280 rgrl_transformation_sptr xform_estimate,
00281 rgrl_scale_sptr scale,
00282 unsigned resolution )
00283 {
00284 rgrl_converge_status_sptr current_status;
00285 rgrl_feature_set_sptr from_set;
00286 rgrl_feature_set_sptr to_set;
00287 rgrl_matcher_sptr matcher;
00288 rgrl_scale_estimator_unwgted_sptr unwgted_scale_est;
00289 rgrl_scale_estimator_wgted_sptr wgted_scale_est;
00290 rgrl_weighter_sptr weighter;
00291 rgrl_match_set_sptr match_set;
00292 vcl_vector<rgrl_estimator_sptr> xform_estimators;
00293 rgrl_estimator_sptr xform_estimator;
00294 bool failed, scale_in_range;
00295 unsigned prev_resol = 0;
00296
00297 failed = false;
00298 scale_in_range = true;
00299 current_xform_estimate_ = xform_estimate;
00300
00301 assert ( data_->has_stage( resolution ) );
00302
00303 do {
00304 data_->get_data_at_stage( resolution, from_set, to_set, matcher, weighter,
00305 unwgted_scale_est, wgted_scale_est, xform_estimators);
00306 match_set = 0;
00307 current_stage_ = resolution;
00308
00309 DebugMacro( 1, " Current resolution "<< resolution <<'\n' );
00310
00311
00312
00313
00314
00315
00316 if ( xform_estimators.empty() )
00317 xform_estimator = initial_xform_estimator;
00318 else xform_estimator = xform_estimators[0];
00319 assert ( xform_estimator );
00320
00321 iterations_at_stage_ = 0;
00322 current_status = 0;
00323 bool should_estimate_scale = true;
00324 int scale_est_count = 0;
00325
00326 do {
00327
00328 DebugMacro( 2, " Computing matches and scales\n" );
00329
00330
00331 match_set= matcher->compute_matches( *from_set,
00332 *to_set,
00333 *current_xform_estimate_,
00334 from_image_region,
00335 to_image_region,
00336 *scale );
00337 current_match_sets_.clear();
00338 current_match_sets_.push_back( match_set );
00339 DebugMacro( 2, " Matches: " << match_set->from_size() <<'\n' );
00340
00341
00342
00343
00344 if ( iterations_for_scale_est_ >= 0 &&
00345 scale_est_count > iterations_for_scale_est_ ) {
00346 should_estimate_scale = false;
00347 }
00348
00349 rgrl_scale_sptr new_scale = 0;
00350 if ( !should_estimate_scale ) {
00351 DebugMacro( 2, "No scale estimation\n" );
00352 }
00353 else if ( match_set->from_size() == 0 ) {
00354 DebugMacro(0, "rgrl_feature_based_registration:: Empty match set!!!\n");
00355 failed = true;
00356 continue;
00357 }
00358 else {
00359 if ( !wgted_scale_est ) {
00360 new_scale = unwgted_scale_est->
00361 estimate_unweighted( *match_set, scale, should_penalize_scaling_ );
00362 } else {
00363 if ( iterations_at_stage_ == 0 && !scale ) {
00364 assert ( unwgted_scale_est );
00365 new_scale = unwgted_scale_est->
00366 estimate_unweighted( *match_set, scale, should_penalize_scaling_);
00367 }
00368 else {
00369 weighter->compute_weights(*scale, *match_set);
00370 new_scale = wgted_scale_est->
00371 estimate_weighted( *match_set, scale, should_penalize_scaling_);
00372 }
00373 }
00374
00375
00376
00377 if ( new_scale ) {
00378 DebugMacro( 2, "New geometric scale = "<<new_scale->geometric_scale()<<'\n' );
00379 if ( new_scale->has_geometric_scale() &&
00380 new_scale->geometric_scale() < expected_min_geometric_scale_ ) {
00381 should_estimate_scale = false;
00382 if (!scale) scale = new_scale;
00383 scale->set_geometric_scale(expected_min_geometric_scale_);
00384 DebugMacro( 2, "Scale below expected_min_geometric_scale. Set to expected_min_geometric_scale.\n" );
00385 }
00386 else {
00387 scale = new_scale;
00388 }
00389 scale_est_count++;
00390 }
00391 }
00392 DebugMacro( 2, "Current geometric scale = "<<scale->geometric_scale()<<'\n' );
00393 assert ( scale );
00394
00395
00396
00397 if ( expected_max_geometric_scale_ > 0 &&
00398 scale->has_geometric_scale() &&
00399 scale->geometric_scale() > expected_max_geometric_scale_) {
00400 scale_in_range = false;
00401 failed = true;
00402 continue;
00403 }
00404
00405 DebugMacro( 2, " Estimate the transformation\n" );
00406
00407
00408
00409
00410
00411
00412
00413
00414 if ( !rgrl_util_irls( match_set, scale, weighter,
00415 *conv_tester_, xform_estimator,
00416 current_xform_estimate_,
00417 false,
00418 this->debug_flag() ) ) {
00419 failed = true;
00420 continue;
00421 }
00422
00423
00424
00425 this->invoke_event(rgrl_event_iteration());
00426
00427
00428
00429 DebugMacro( 2, " Updating scale estimates and checking for validity\n" );
00430
00431 match_set->remap_from_features( *current_xform_estimate_ );
00432 weighter->compute_weights( *scale, *match_set );
00433
00434
00435 {
00436 bool ret_success;
00437 vnl_vector<double> scaling;
00438 ret_success = rgrl_util_geometric_scaling_factors( *match_set, scaling );
00439 if ( ret_success ) {
00440 current_xform_estimate_->set_scaling_factors( scaling );
00441 if (should_penalize_scaling_) {
00442 for ( unsigned ds=0; ds < scaling.size(); ++ds ) {
00443 if (scaling[ds] < 1e-5) {
00444 DebugMacro( 1," Scaling of dimension "<<ds<<" too high\n");
00445 failed = true;
00446 }
00447 }
00448 }
00449 }
00450 else
00451 WarningMacro( "cannot compute scaling factors!!!" );
00452 }
00453
00454 #if 0
00455
00456
00457
00458 if ( should_estimate_scale ) {
00459 if ( !wgted_scale_est )
00460 scale = unwgted_scale_est->
00461 estimate_unweighted( *match_set, scale, should_penalize_scaling_ );
00462 else
00463 scale = wgted_scale_est->
00464 estimate_weighted( *match_set, scale, should_penalize_scaling_ );
00465 DebugMacro( 2, " Geometric scale after converged = "<< scale->geometric_scale()<<'\n' );
00466 }
00467 #endif // 0
00468
00469
00470
00471 DebugMacro( 2, " Perform convergence test\n" );
00472 current_status =
00473 conv_tester_->compute_status( current_status,
00474 current_xform_estimate_,
00475 xform_estimator,
00476 match_set, scale,
00477 should_penalize_scaling_);
00478 DebugMacro( 3, "run: (iterations = " << iterations_at_stage_ << ") oscillation count = " << current_status->oscillation_count() << '\n' );
00479 DebugMacro( 3, "run: error = " << current_status->error() << vcl_endl );
00480 DebugMacro( 3, "run: error_diff = " << current_status->error_diff() << vcl_endl );
00481
00482 ++iterations_at_stage_;
00483 }
00484 while ( !failed &&
00485 !current_status->has_converged() &&
00486 !current_status->has_stagnated() &&
00487 iterations_at_stage_ < max_icp_iter_ );
00488
00489 if ( failed ) {
00490 if ( !scale_in_range )
00491 DebugMacro( 1, " Geometric scale above the expected value\n" );
00492 else
00493 DebugMacro( 1, " Failed with empty match set, or irls estimation\n" );
00494 continue;
00495 }
00496 if ( current_status->has_converged() )
00497 DebugMacro( 1, " CONVERGED\n" );
00498 if ( current_status->has_stagnated() )
00499 DebugMacro( 1, " STAGNATED\n" );
00500 if ( iterations_at_stage_ == max_icp_iter_ )
00501 DebugMacro( 1, " ICP iteration reached maximum ("<<max_icp_iter_<<" )\n" );
00502
00503
00504
00505
00506 prev_resol = resolution;
00507 initialize_for_next_resolution( from_image_region, to_image_region,
00508 current_xform_estimate_, resolution );
00509 int level_diff = prev_resol - resolution;
00510 double dim_increase = data_->dimension_increase_for_next_stage(prev_resol);
00511
00512 scale->set_geometric_scale( scale->geometric_scale()*
00513 vcl_pow(dim_increase, level_diff) );
00514 }
00515 while ( !failed && ( resolution != 0 || prev_resol != 0 ) );
00516
00517 DebugMacro( 1, "Estimation complete\n" );
00518
00519
00520
00521
00522
00523
00524
00525 if ( !failed ){
00526 DebugMacro( 1, "Obj value after convergence = "<<current_status->objective_value()<<'\n');
00527 if ( !best_status_ ||
00528 current_status->objective_value() < best_status_->objective_value() ) {
00529 best_xform_estimate_ = current_xform_estimate_;
00530 if (best_scales_.size() != 1)
00531 best_scales_.resize(1);
00532 best_scales_[0] = scale;
00533 if (best_matches_.size() != 1)
00534 best_matches_.resize(1);
00535 best_matches_[0] = match_set;
00536 best_status_ = current_status;
00537 DebugMacro( 1, "Set best xform estimate\n" );
00538 }
00539 }
00540 }
00541
00542
00543 void
00544 rgrl_feature_based_registration::
00545 register_multi_feature( rgrl_mask_box from_image_region,
00546 rgrl_mask_box to_image_region,
00547 rgrl_estimator_sptr initial_xform_estimator,
00548 rgrl_transformation_sptr xform_estimate,
00549 rgrl_scale_sptr prior_scale,
00550 unsigned resolution )
00551 {
00552 rgrl_converge_status_sptr current_status;
00553 vcl_vector<rgrl_feature_set_sptr> from_sets;
00554 vcl_vector<rgrl_feature_set_sptr> to_sets;
00555 vcl_vector<rgrl_matcher_sptr> matchers;
00556 vcl_vector<rgrl_scale_estimator_unwgted_sptr> unwgted_scale_ests;
00557 vcl_vector<rgrl_scale_estimator_wgted_sptr> wgted_scale_ests;
00558 vcl_vector<rgrl_weighter_sptr> weighters;
00559 rgrl_set_of<rgrl_scale_sptr> scales;
00560 vcl_vector<rgrl_estimator_sptr> xform_estimators;
00561 rgrl_estimator_sptr xform_estimator;
00562 bool failed, scale_in_range, use_prior_scale;
00563 unsigned prev_resol = 0;
00564
00565 use_prior_scale = false;
00566 if ( prior_scale ) use_prior_scale = true;
00567 scale_in_range = true;
00568 failed = false;
00569 current_xform_estimate_ = xform_estimate;
00570
00571 assert ( data_->has_stage( resolution ) );
00572
00573 do {
00574 data_->get_data_at_stage( resolution, from_sets, to_sets, matchers,
00575 weighters, unwgted_scale_ests,
00576 wgted_scale_ests, xform_estimators);
00577 current_stage_ = resolution;
00578 unsigned data_count = from_sets.size();
00579
00580 DebugMacro( 1, " Current resolution "<< resolution <<'\n' );
00581
00582
00583
00584
00585 current_match_sets_.clear();
00586 scales.clear();
00587 current_match_sets_.resize( data_count );
00588 scales.resize( data_count );
00589
00590
00591
00592
00593
00594
00595 if ( xform_estimators.size() == 0 )
00596 xform_estimator = initial_xform_estimator;
00597 else xform_estimator = xform_estimators[0];
00598 assert ( xform_estimator );
00599
00600
00601
00602
00603 if ( use_prior_scale ) {
00604 DebugMacro( 2, "Prior scale = "<<prior_scale->geometric_scale()<<'\n' );
00605 for ( unsigned int fs = 0; fs < data_count; ++fs )
00606 scales[fs] = prior_scale;
00607 }
00608
00609 iterations_at_stage_ = 0;
00610 current_status = 0;
00611 bool should_estimate_scale = true;
00612 int scale_est_count = 0;
00613
00614 do {
00615
00616 DebugMacro( 2, " Computing matches and scales\n" );
00617
00618
00619 for ( unsigned int fs=0; fs < data_count; ++fs ) {
00620 DebugMacro( 2, " Data set " << fs << vcl_endl );
00621 rgrl_match_set_sptr new_matches =
00622 matchers[fs]->compute_matches( *from_sets[fs],
00623 *to_sets[fs],
00624 *current_xform_estimate_,
00625 from_image_region,
00626 to_image_region,
00627 *scales[fs] );
00628 DebugMacro( 2, " Matches: " << new_matches->from_size() <<" ("<<new_matches<<")\n" );
00629
00630
00631
00632
00633 if ( iterations_for_scale_est_ >= 0 &&
00634 scale_est_count > iterations_for_scale_est_ ) {
00635 should_estimate_scale = false;
00636 }
00637
00638 rgrl_scale_sptr new_scale = 0;
00639 if ( !should_estimate_scale ) {
00640 DebugMacro( 2, "No scale estimation\n" );
00641 }
00642 else if ( new_matches->from_size() == 0 ) {
00643 DebugMacro(0, "Empty match set!!!\n");
00644 failed = true;
00645 continue;
00646 }
00647 else {
00648 if ( !wgted_scale_ests[fs] ) {
00649 new_scale = unwgted_scale_ests[fs]->
00650 estimate_unweighted( *new_matches, scales[fs], should_penalize_scaling_ );
00651 } else {
00652 if ( iterations_at_stage_ == 0 && !scales[fs] ) {
00653 assert ( unwgted_scale_ests[fs] );
00654 new_scale = unwgted_scale_ests[fs]->
00655 estimate_unweighted( *new_matches, scales[fs], should_penalize_scaling_);
00656 }
00657 else {
00658 weighters[fs]->compute_weights(*scales[fs], *new_matches);
00659 new_scale = wgted_scale_ests[fs]->
00660 estimate_weighted( *new_matches, scales[fs], should_penalize_scaling_);
00661 }
00662 }
00663
00664 if ( new_scale ) {
00665 DebugMacro( 2, "New geometric scale = "<<new_scale->geometric_scale()<<'\n' );
00666 if ( new_scale->has_geometric_scale() &&
00667 new_scale->geometric_scale() < expected_min_geometric_scale_ ) {
00668 should_estimate_scale = false;
00669 if (!scales[fs]) scales[fs] = new_scale;
00670 scales[fs]->set_geometric_scale(expected_min_geometric_scale_);
00671 DebugMacro( 2, "Scale below expected_min_geometric_scale. Set to expected_min_geometric_scale.\n" );
00672 }
00673 else {
00674 scales[fs] = new_scale;
00675 }
00676 scale_est_count++;
00677 }
00678 }
00679 assert ( scales[fs] );
00680
00681
00682
00683 if ( expected_max_geometric_scale_ > 0 &&
00684 scales[fs]->has_geometric_scale() &&
00685 scales[fs]->geometric_scale() > expected_max_geometric_scale_) {
00686 scale_in_range = false;
00687 failed = true;
00688 }
00689
00690
00691
00692 current_match_sets_[fs] = new_matches;
00693 }
00694
00695 DebugMacro( 2, " Estimate the transformation\n" );
00696
00697
00698
00699
00700
00701
00702
00703 if ( !rgrl_util_irls( current_match_sets_, scales, weighters,
00704 *conv_tester_, xform_estimator,
00705 current_xform_estimate_,
00706 false,
00707 this->debug_flag() ) ) {
00708 failed = true;
00709 continue;
00710 }
00711
00712
00713
00714 this->invoke_event(rgrl_event_iteration());
00715
00716
00717
00718 DebugMacro( 2, " Updating scale estimates and checking for validity\n" );
00719 for ( unsigned int fs=0; fs < data_count; ++fs ) {
00720 if ( current_match_sets_[fs]->from_size() > 0 ) {
00721 current_match_sets_[fs]->remap_from_features( *current_xform_estimate_ );
00722 weighters[fs]->compute_weights( *scales[fs], *current_match_sets_[fs] );
00723
00724
00725 {
00726 bool ret_success;
00727 vnl_vector<double> scaling;
00728 ret_success = rgrl_util_geometric_scaling_factors( current_match_sets_, scaling );
00729 if ( ret_success ) {
00730 current_xform_estimate_->set_scaling_factors( scaling );
00731 if (should_penalize_scaling_) {
00732 for ( unsigned ds=0; ds < scaling.size(); ++ds ) {
00733 if (scaling[ds] < 1e-5) {
00734 DebugMacro( 1," Scaling of dimension "<<ds<<" too high\n");
00735 failed = true;
00736 }
00737 }
00738 }
00739 }
00740 else
00741 WarningMacro( "cannot compute scaling factors!!!" );
00742 }
00743
00744 #if 0
00745
00746
00747 if ( should_estimate_scale ) {
00748 if ( !wgted_scale_ests[fs] )
00749 scales[fs] = unwgted_scale_ests[fs]->
00750 estimate_unweighted( *current_match_sets_[fs], scales[fs], should_penalize_scaling_ );
00751 else scales[fs] = wgted_scale_ests[fs]->
00752 estimate_weighted( *current_match_sets_[fs], scales[fs], should_penalize_scaling_ );
00753 DebugMacro( 2, " Geometric scale after converged = "<< scales[fs]->geometric_scale()<<'\n' );
00754 }
00755 #endif // 0
00756 }
00757 }
00758
00759
00760
00761 DebugMacro( 2, " Perform convergence test\n" );
00762 current_status =
00763 conv_tester_->compute_status( current_status,
00764 current_xform_estimate_,
00765 xform_estimator,
00766 current_match_sets_, scales,
00767 should_penalize_scaling_);
00768 DebugMacro( 3, "run: (iterations = " << iterations_at_stage_ << ") oscillation count = " << current_status->oscillation_count() << '\n' );
00769 DebugMacro( 3, "run: error = " << current_status->error() << vcl_endl );
00770 DebugMacro( 3, "run: error_diff = " << current_status->error_diff() << vcl_endl );
00771
00772 ++iterations_at_stage_;
00773 }
00774 while ( !failed &&
00775 !current_status->has_converged() &&
00776 !current_status->has_stagnated() &&
00777 iterations_at_stage_ < max_icp_iter_ );
00778
00779 if ( failed ) {
00780 if ( !scale_in_range )
00781 DebugMacro( 2, " Geometric scale above the expected value\n" );
00782 else
00783 DebugMacro( 2, " Failed with empty match set, or feature_based\n" );
00784 continue;
00785 }
00786 if ( current_status->has_converged() )
00787 DebugMacro( 1, " CONVERGED\n" );
00788 if ( current_status->has_stagnated() )
00789 DebugMacro( 1, " STAGNATED\n" );
00790 if ( iterations_at_stage_ == max_icp_iter_ )
00791 DebugMacro( 1, " ICP iteration reached maximum ("<<max_icp_iter_<<" )\n" );
00792
00793
00794
00795
00796 prev_resol = resolution;
00797 initialize_for_next_resolution( from_image_region, to_image_region,
00798 current_xform_estimate_, resolution );
00799 int level_diff = prev_resol - resolution;
00800 double dim_increase = data_->dimension_increase_for_next_stage(prev_resol);
00801 double scale_multipler = vcl_pow(dim_increase, level_diff);
00802 for ( unsigned int fs=0; fs < data_count; ++fs ) {
00803 scales[fs]->set_geometric_scale( scales[fs]->geometric_scale()*scale_multipler );
00804 }
00805
00806 use_prior_scale = true;
00807 prior_scale = scales[0];
00808 }
00809 while ( !failed && ( resolution != 0 || prev_resol != 0) );
00810
00811 DebugMacro( 1, "Estimation complete\n" );
00812
00813
00814
00815
00816
00817
00818
00819 if ( !failed ){
00820 DebugMacro( 1, "Obj value after convergence = "<<current_status->objective_value()<<'\n');
00821 if ( !best_status_ ||
00822 current_status->objective_value() < best_status_->objective_value() ) {
00823 best_xform_estimate_ = current_xform_estimate_;
00824 best_scales_ = scales;
00825 best_matches_ = current_match_sets_;
00826 best_status_ = current_status;
00827 DebugMacro( 1, "Set best xform estimate\n" );
00828 }
00829 }
00830 }
00831
00832
00833 void
00834 rgrl_feature_based_registration::
00835 initialize_for_next_resolution( rgrl_mask_box & from_image_region,
00836 rgrl_mask_box & to_image_region,
00837 rgrl_transformation_sptr & xform_estimate,
00838 unsigned & current_resol ) const
00839 {
00840
00841
00842 unsigned new_resol = current_resol;
00843 int next_resol = new_resol - 1;
00844 for ( ; next_resol >=0 ; --next_resol) {
00845 if ( data_->has_stage(next_resol) ) {
00846 new_resol = next_resol;
00847 break;
00848 }
00849 }
00850
00851
00852
00853 if ( new_resol == current_resol ) return;
00854
00855
00856
00857
00858
00859 int level_diff = current_resol - new_resol;
00860 double dim_increase = data_->dimension_increase_for_next_stage(current_resol);
00861 double scale = vcl_pow(dim_increase, level_diff);
00862
00863 from_image_region.set_x0( from_image_region.x0()*scale );
00864 from_image_region.set_x1( from_image_region.x1()*scale );
00865
00866 xform_estimate = xform_estimate->scale_by( scale );
00867 current_resol = new_resol;
00868 }