00001
00002
00003
00004
00005 #include "rgrl_util.h"
00006 #include <vcl_vector.h>
00007 #include <vcl_string.h>
00008 #include <vcl_cassert.h>
00009 #include <vcl_algorithm.h>
00010
00011 #include <vnl/vnl_vector.h>
00012 #include <vnl/algo/vnl_svd.h>
00013 #include <vnl/vnl_math.h>
00014
00015 #include <rgrl/rgrl_converge_status.h>
00016 #include <rgrl/rgrl_converge_status_sptr.h>
00017 #include <rgrl/rgrl_convergence_tester.h>
00018 #include <rgrl/rgrl_weighter.h>
00019 #include <rgrl/rgrl_estimator.h>
00020 #include <rgrl/rgrl_match_set.h>
00021 #include <rgrl/rgrl_mask.h>
00022
00023
00024 static
00025 rgrl_mask_box
00026 global_region_from_inv_xformed_points(
00027 vcl_vector< vnl_vector<double> > const& inv_mapped_pts,
00028 rgrl_mask_sptr const& from_image_roi,
00029 rgrl_mask_box const& current_region,
00030 bool union_with_curr,
00031 double drastic_change_ratio)
00032 {
00033 typedef vcl_vector<vnl_vector<double> > pt_vector;
00034 typedef pt_vector::const_iterator pt_iter;
00035
00036 const vnl_vector<double> from_x0 = from_image_roi->x0();
00037 const vnl_vector<double> from_x1 = from_image_roi->x1();
00038 const unsigned m = from_x0.size();
00039 const int debug_flag = 0;
00040
00041 vnl_vector<double> inv_mapped_x0 = from_image_roi->x1();
00042 vnl_vector<double> inv_mapped_x1 = from_image_roi->x0();
00043 for ( pt_iter pitr = inv_mapped_pts.begin(); pitr != inv_mapped_pts.end(); ++pitr ) {
00044
00045 vnl_vector<double> const& inv_mapped_pt = *pitr;
00046
00047
00048 for ( unsigned d=0; d < m; ++d ) {
00049 if (inv_mapped_pt[d] < inv_mapped_x0[d]) inv_mapped_x0[d] = inv_mapped_pt[d];
00050 if (inv_mapped_pt[d] > inv_mapped_x1[d]) inv_mapped_x1[d] = inv_mapped_pt[d];
00051 }
00052 }
00053
00054 DebugFuncMacro( debug_flag, 1, "Global Region after inv-mapping: "
00055 << inv_mapped_x0 << " - " << inv_mapped_x1 << vcl_endl );
00056
00057
00058
00059 vnl_vector<double> region_x0(m);
00060 vnl_vector<double> region_x1(m);
00061
00062 for ( unsigned d=0; d < m; ++d ) {
00063 region_x0[d] = (inv_mapped_x0[d] > from_x0[d])? inv_mapped_x0[d]:from_x0[d];
00064 region_x1[d] = (inv_mapped_x1[d] < from_x1[d])? inv_mapped_x1[d]:from_x1[d];
00065 if ( region_x0[d] > from_x1[d] ) region_x0[d] = from_x1[d];
00066 if ( region_x1[d] < from_x0[d] ) region_x1[d] = from_x0[d];
00067 }
00068 if (region_x0 == region_x1)
00069 return current_region;
00070
00071 DebugFuncMacro( debug_flag, 1, "Global Region after intersecting with ROI: "
00072 << region_x0 << " - " << region_x1 << vcl_endl );
00073
00074
00075 if (union_with_curr) {
00076 for ( unsigned d=0; d < m; ++d ) {
00077 if (region_x0[d] > current_region.x0()[d]) region_x0[d] = current_region.x0()[d];
00078 if (region_x1[d] < current_region.x1()[d]) region_x1[d] = current_region.x1()[d];
00079 }
00080 }
00081
00082 DebugFuncMacro( debug_flag, 1, "Global Region after union with prev region: "
00083 << region_x0 << " - " << region_x1 << vcl_endl );
00084
00085
00086
00087 bool changed =
00088 ( (region_x0 - current_region.x0()).inf_norm() > 1 ||
00089 (region_x1 - current_region.x1()).inf_norm() > 1);
00090 bool drastic_changed = false;
00091 double prev_space = 1, new_space = 1;
00092 vnl_vector<double> prev_space_dim = current_region.x1() - current_region.x0();
00093 vnl_vector<double> new_space_dim = region_x1 - region_x0;
00094 for ( unsigned d=0; d < m; ++d ) {
00095 prev_space *= prev_space_dim[d];
00096 new_space *= new_space_dim[d];
00097 }
00098 if ( union_with_curr && new_space/prev_space > drastic_change_ratio ) {
00099 drastic_changed = true;
00100 }
00101
00102 rgrl_mask_box region = current_region;
00103 if ( changed && !drastic_changed) {
00104 region.set_x0(region_x0);
00105 region.set_x1(region_x1);
00106 }
00107
00108 DebugFuncMacro( debug_flag, 1, "Global Region finalized: "
00109 << region_x0 << " - " << region_x1 << vcl_endl );
00110
00111 return region;
00112
00113 }
00114
00115 rgrl_mask_box
00116 rgrl_util_estimate_global_region_with_inverse_xform(
00117 rgrl_mask_sptr const& from_image_roi,
00118 rgrl_mask_sptr const& to_image_roi,
00119 rgrl_mask_box const& current_region,
00120 rgrl_transformation const& inv_xform,
00121 bool union_with_curr,
00122 double drastic_change_ratio)
00123 {
00124
00125
00126
00127
00128
00129
00130
00131
00132 typedef vcl_vector<vnl_vector<double> > pt_vector;
00133 typedef pt_vector::iterator pt_iter;
00134
00135 vnl_vector<double> const& to_x0 = to_image_roi->x0();
00136 vnl_vector<double> const& to_x1 = to_image_roi->x1();
00137 const unsigned m = to_x0.size();
00138 assert( 2 <= m && m <= 3 );
00139
00140
00141 vcl_vector<int> ind( m );
00142 for( unsigned i=0; i<m; ++i )
00143 ind[i] = i;
00144
00145
00146
00147 pt_vector to_boun_pts;
00148 pt_vector inv_mapped_pts;
00149 vnl_vector<double> pt( m );
00150
00151
00152 to_boun_pts.reserve( 500 );
00153 inv_mapped_pts.reserve( 500 );
00154
00155
00156
00157 do{
00158
00159 const double step = 30;
00160 for (double i = to_x0[ind[0]]; i<= to_x1[ind[0]]; i+=step) {
00161 for (double j = to_x0[ind[1]]; j<= to_x1[ind[1]]; j+=step) {
00162
00163 if (m == 3) {
00164 for (double k = to_x0[ind[2]]; k<= to_x1[ind[2]]; k+=step) {
00165 pt[ind[0]] = i;
00166 pt[ind[1]] = j;
00167 pt[ind[2]] = k;
00168 to_boun_pts.push_back(pt);
00169 }
00170 } else {
00171 pt[ind[0]] = i;
00172 pt[ind[1]] = j;
00173 to_boun_pts.push_back(pt);
00174 }
00175
00176 }
00177 }
00178
00179
00180
00181 while(vcl_next_permutation(ind.begin()+1, ind.end() ) ) ;
00182
00183 }while( vcl_next_permutation(ind.begin(), ind.end() ) );
00184
00185
00186
00187
00188
00189 vnl_vector<double> inv_mapped_pt( m );
00190 for ( pt_iter pitr = to_boun_pts.begin(); pitr != to_boun_pts.end(); ++pitr ) {
00191
00192 inv_xform.map_location( *pitr, inv_mapped_pt );
00193 inv_mapped_pts.push_back( inv_mapped_pt );
00194 }
00195
00196
00197
00198 return global_region_from_inv_xformed_points( inv_mapped_pts,
00199 from_image_roi,
00200 current_region,
00201 union_with_curr,
00202 drastic_change_ratio );
00203 }
00204
00205
00206 rgrl_mask_box
00207 rgrl_util_estimate_global_region( rgrl_mask_sptr const& from_image_roi,
00208 rgrl_mask_sptr const& to_image_roi,
00209 rgrl_mask_box const& current_region,
00210 rgrl_transformation const& curr_xform,
00211 bool union_with_curr,
00212 double drastic_change_ratio)
00213 {
00214
00215
00216
00217
00218
00219
00220
00221
00222 typedef vcl_vector<vnl_vector<double> > pt_vector;
00223 typedef pt_vector::iterator pt_iter;
00224 const double epsilon = 1;
00225 const double eps_squared = epsilon*epsilon;
00226
00227 vnl_vector<double> const& from_x0 = from_image_roi->x0();
00228 vnl_vector<double> const& from_x1 = from_image_roi->x1();
00229 const unsigned m = from_x0.size();
00230 assert( 2 <= m && m <= 3 );
00231
00232
00233 vcl_vector<int> ind( m );
00234 for( unsigned i=0; i<m; ++i )
00235 ind[i] = i;
00236
00237
00238
00239
00240 vnl_vector<double> const& to_x0 = to_image_roi->x0();
00241 vnl_vector<double> const& to_x1 = to_image_roi->x1();
00242 pt_vector to_boun_pts;
00243 pt_vector inv_mapped_pts;
00244 vnl_vector<double> pt( m );
00245
00246
00247 to_boun_pts.reserve( 500 );
00248 inv_mapped_pts.reserve( 500 );
00249
00250
00251
00252 do{
00253
00254 const double step = 30;
00255 for (double i = to_x0[ind[0]]; i<= to_x1[ind[0]]; i+=step) {
00256 for (double j = to_x0[ind[1]]; j<= to_x1[ind[1]]&&j>= to_x0[ind[1]]; j+=(to_x1[ind[1]]-to_x0[ind[1]])) {
00257
00258 if (m == 3) {
00259 for (double k = to_x0[ind[2]]; k<= to_x1[ind[2]]&&k>= to_x0[ind[2]]; k+=(to_x1[ind[2]]-to_x0[ind[2]])) {
00260 pt[ind[0]] = i;
00261 pt[ind[1]] = j;
00262 pt[ind[2]] = k;
00263 to_boun_pts.push_back(pt);
00264 }
00265 } else {
00266 pt[ind[0]] = i;
00267 pt[ind[1]] = j;
00268 to_boun_pts.push_back(pt);
00269 }
00270
00271 }
00272 }
00273
00274
00275
00276 while(vcl_next_permutation(ind.begin()+1, ind.end() ) ) ;
00277
00278 }while( vcl_next_permutation(ind.begin(), ind.end() ) );
00279
00280
00281
00282
00283
00284 if( curr_xform.is_invertible() ) {
00285
00286 rgrl_transformation_sptr inv_xform = curr_xform.inverse_transform();
00287 vnl_vector<double> inv_mapped_pt( m );
00288 for ( pt_iter pitr = to_boun_pts.begin(); pitr != to_boun_pts.end(); ++pitr ) {
00289
00290 inv_xform->map_location( *pitr, inv_mapped_pt );
00291 inv_mapped_pts.push_back( inv_mapped_pt );
00292 }
00293
00294 } else {
00295
00296
00297
00298 pt_vector from_pts;
00299 const double step_eps = 1e-10;
00300 for (double i = from_x0[0];
00301 i<= from_x1[0]&&i>= from_x0[0];
00302 i+= (from_x1[0]-from_x0[0])/10-step_eps) {
00303
00304 for (double j = from_x0[1];
00305 j<= from_x1[1]&&j>=from_x0[1];
00306 j+= (from_x1[1]-from_x0[1])/10-step_eps) {
00307 if (m == 3) {
00308 for (double k = from_x0[2];
00309 k<= from_x1[2]&&k>=from_x0[2];
00310 k+= (from_x1[2]-from_x0[2])/10-step_eps) {
00311 vnl_vector<double> pt(3);
00312 pt[0] = i;
00313 pt[1] = j;
00314 pt[2] = k;
00315 from_pts.push_back(pt);
00316 }
00317 }
00318 else {
00319 vnl_vector<double> pt(2);
00320 pt[0] = i;
00321 pt[1] = j;
00322 from_pts.push_back(pt);
00323 }
00324 }
00325 }
00326
00327
00328 pt_vector to_mapped_pts;
00329 vnl_vector<double> to_pt;
00330 for (pt_iter pitr = from_pts.begin(); pitr != from_pts.end(); ++pitr) {
00331 curr_xform.map_location(*pitr, to_pt);
00332 to_mapped_pts.push_back(to_pt);
00333 }
00334
00335
00336
00337
00338 for ( pt_iter pitr = to_boun_pts.begin(); pitr != to_boun_pts.end(); ++pitr ) {
00339 double min_sqr_dist = vnl_vector_ssd(to_mapped_pts[0], (*pitr));
00340 unsigned int min_index = 0;
00341 for (unsigned int i = 1; i<to_mapped_pts.size(); ++i) {
00342 double sqr_dist = vnl_vector_ssd(to_mapped_pts[i], (*pitr));
00343 if (sqr_dist < min_sqr_dist) {
00344 min_sqr_dist = sqr_dist;
00345 min_index = i;
00346 }
00347 }
00348
00349 vnl_vector<double> to_delta, from_next_est;
00350 vnl_vector<double> inv_mapped_pt = from_pts[min_index];
00351 curr_xform.inv_map(*pitr, false, to_delta, inv_mapped_pt, from_next_est);
00352 vnl_vector<double> fwd_mapp_pt = curr_xform.map_location(inv_mapped_pt);
00353 if (vnl_vector_ssd(fwd_mapp_pt, *pitr) > eps_squared)
00354 return current_region;
00355
00356 inv_mapped_pts.push_back( inv_mapped_pt );
00357
00358 }
00359 }
00360
00361
00362
00363 return global_region_from_inv_xformed_points( inv_mapped_pts,
00364 from_image_roi,
00365 current_region,
00366 union_with_curr,
00367 drastic_change_ratio );
00368 }
00369
00370 double
00371 rgrl_util_geometric_error_scaling( rgrl_match_set const& match_set )
00372 {
00373 vnl_vector<double> factors;
00374 bool success = rgrl_util_geometric_scaling_factors( match_set, factors );
00375 if ( !success )
00376 return 0.0;
00377
00378
00379
00380 double change_in_fst = vnl_math_max( factors[0],
00381 1/factors[0] );
00382 double change_in_snd = vnl_math_max( factors[1],
00383 1/factors[1] );
00384
00385 double scaling = vnl_math_max( change_in_fst, change_in_snd );
00386
00387
00388 return scaling;
00389
00390 #if 0 // commented out
00391
00392
00393 double ratio_from = ev_fst_from/ev_snd_from;
00394 double ratio_mapped = ev_fst_mapped/ev_snd_mapped;
00395 double distortion = vnl_math_max( ratio_from/ratio_mapped,
00396 ratio_mapped/ratio_from );
00397
00398 return distortion;
00399 #endif // 0
00400 }
00401
00402 double
00403 rgrl_util_geometric_error_scaling( rgrl_set_of<rgrl_match_set_sptr> const& current_match_sets )
00404 {
00405 vnl_vector<double> factors;
00406 bool success = rgrl_util_geometric_scaling_factors( current_match_sets, factors );
00407 if ( !success )
00408 return 0.0;
00409
00410
00411
00412 double change_in_fst = vnl_math_max( factors[0],
00413 1/factors[0] );
00414 double change_in_snd = vnl_math_max( factors[1],
00415 1/factors[1] );
00416
00417 double scaling = vnl_math_max( change_in_fst, change_in_snd );
00418
00419 return scaling;
00420 }
00421
00422 bool
00423 rgrl_util_geometric_scaling_factors( rgrl_match_set const& match_set,
00424 vnl_vector<double>& factors )
00425 {
00426 typedef rgrl_match_set::const_from_iterator FIter;
00427
00428 if ( match_set.from_size() == 0 ) return false;
00429
00430
00431
00432
00433 unsigned int m = match_set.from_begin().from_feature()->location().size();
00434
00435
00436
00437 vnl_vector<double> from_centre( m, 0.0 );
00438 vnl_vector<double> mapped_centre( m, 0.0 );
00439 for ( FIter fi = match_set.from_begin(); fi != match_set.from_end(); ++fi ) {
00440 from_centre += fi.from_feature()->location();
00441 mapped_centre += fi.mapped_from_feature()->location();
00442 }
00443 from_centre /= match_set.from_size();
00444 mapped_centre /= match_set.from_size();
00445
00446
00447
00448 vnl_matrix<double> cov_matrix_from(m,m,0.0);
00449 vnl_matrix<double> cov_matrix_mapped(m,m,0.0);
00450 for ( FIter fi = match_set.from_begin(); fi != match_set.from_end(); ++fi ) {
00451 cov_matrix_from +=
00452 outer_product(fi.from_feature()->location() - from_centre,
00453 fi.from_feature()->location() - from_centre);
00454 cov_matrix_mapped +=
00455 outer_product(fi.mapped_from_feature()->location() - mapped_centre,
00456 fi.mapped_from_feature()->location() - mapped_centre);
00457 }
00458 if( match_set.from_size()<m+1 )
00459 return false;
00460
00461 cov_matrix_from /= match_set.from_size();
00462 cov_matrix_mapped /= match_set.from_size();
00463
00464
00465
00466 vnl_svd<double> svd_from (cov_matrix_from );
00467 vnl_svd<double> svd_mapped (cov_matrix_mapped );
00468
00469 double sv_from, sv_mapped;
00470 factors.set_size( m );
00471 for ( unsigned i=0; i<m; ++i ) {
00472 sv_from = vcl_sqrt( vnl_math_max( svd_from.W(i), 1e-16 ) );
00473 sv_mapped = vcl_sqrt( vnl_math_max( svd_mapped.W(i), 1e-16 ) );
00474 factors[i] = sv_mapped / sv_from;
00475 }
00476
00477 return true;
00478 }
00479
00480 bool
00481 rgrl_util_geometric_scaling_factors( rgrl_set_of<rgrl_match_set_sptr> const& current_match_sets,
00482 vnl_vector<double>& factors )
00483 {
00484 typedef rgrl_match_set::const_from_iterator FIter;
00485
00486 if ( current_match_sets.size() == 0 ) return false;
00487
00488
00489
00490
00491 unsigned int i=0;
00492 while ( current_match_sets[i]->from_size() == 0 && i<current_match_sets.size() )
00493 ++i;
00494 if ( i==current_match_sets.size() ) return false;
00495
00496
00497 const unsigned int from_dim = current_match_sets[i]->from_begin().from_feature()->location().size();
00498 const unsigned int mapped_dim = current_match_sets[i]->from_begin().mapped_from_feature()->location().size();
00499
00500 if( from_dim != mapped_dim ) {
00501
00502
00503 factors.set_size(0);
00504 return true;
00505 }
00506
00507
00508 const unsigned int m = from_dim;
00509
00510
00511
00512 vnl_vector<double> from_centre( m, 0.0 );
00513 vnl_vector<double> mapped_centre( m, 0.0 );
00514 unsigned num = 0;
00515 for (unsigned int i=0; i<current_match_sets.size(); ++i) {
00516 rgrl_match_set const& match_set = *(current_match_sets[i]);
00517 num += match_set.from_size();
00518 for ( FIter fi = match_set.from_begin(); fi != match_set.from_end(); ++fi ) {
00519 from_centre += fi.from_feature()->location();
00520 mapped_centre += fi.mapped_from_feature()->location();
00521 }
00522 }
00523 if( num<m+1 )
00524 return false;
00525
00526 from_centre /= double(num);
00527 mapped_centre /= double(num);
00528
00529
00530
00531 vnl_matrix<double> cov_matrix_from(m,m,0.0);
00532 vnl_matrix<double> cov_matrix_mapped(m,m,0.0);
00533 for (unsigned int i=0; i<current_match_sets.size(); ++i) {
00534 rgrl_match_set const& match_set = *(current_match_sets[i]);
00535 for ( FIter fi = match_set.from_begin(); fi != match_set.from_end(); ++fi ) {
00536 cov_matrix_from +=
00537 outer_product(fi.from_feature()->location() - from_centre,
00538 fi.from_feature()->location() - from_centre);
00539 cov_matrix_mapped +=
00540 outer_product(fi.mapped_from_feature()->location() - mapped_centre,
00541 fi.mapped_from_feature()->location() - mapped_centre);
00542 }
00543 }
00544 cov_matrix_from /= double(num);
00545 cov_matrix_mapped /= double(num);
00546
00547
00548
00549 vnl_svd<double> svd_from (cov_matrix_from );
00550 vnl_svd<double> svd_mapped (cov_matrix_mapped );
00551
00552 double sv_from, sv_mapped;
00553 factors.set_size( m );
00554 for ( unsigned i=0; i<m; ++i ) {
00555 sv_from = vnl_math_max( svd_from.W(i), 1e-16 );
00556 sv_mapped = vnl_math_max( svd_mapped.W(i), 1e-16 );
00557
00558
00559
00560 factors[i] = vcl_sqrt( sv_mapped / sv_from );
00561 }
00562
00563 return true;
00564 }
00565
00566
00567 void
00568 rgrl_util_extract_region_locations( vnl_vector< double > const& center,
00569 vcl_vector< vnl_vector<double> > const& basis_dirs,
00570 vnl_vector< double > const& basis_radii,
00571 vcl_vector< vnl_vector<int> > & pixel_locations )
00572 {
00573
00574
00575 unsigned int dimension = center.size();
00576 pixel_locations.clear();
00577 assert( center.size() == basis_dirs.size() );
00578 assert( center.size() == basis_dirs[0].size() );
00579 assert( center.size() == basis_radii.size() );
00580
00581
00582
00583
00584
00585
00586
00587
00588 vcl_vector< vnl_vector<double> > corner_points;
00589 int num_corners = vnl_math_rnd( vcl_exp( dimension * vcl_log(2.0) ));
00590 corner_points.reserve( num_corners );
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 corner_points.push_back( center );
00605
00606 for ( unsigned int i=0; i<dimension; ++i )
00607 {
00608
00609
00610
00611
00612 vnl_vector<double> offset = basis_dirs[i] * basis_radii[i];
00613 unsigned curr_size = corner_points.size();
00614 for ( unsigned int j=0; j<curr_size; ++j )
00615 {
00616 corner_points.push_back( corner_points[j] + offset );
00617 corner_points[j] -= offset;
00618 }
00619 }
00620
00621
00622
00623
00624
00625 vnl_vector<double> lower = center;
00626 vnl_vector<double> upper = center;
00627
00628 for ( unsigned int i=0; i<corner_points.size(); ++i )
00629 {
00630 for ( unsigned int j=0; j<dimension; ++j )
00631 {
00632 if ( lower[j] > corner_points[i][j] )
00633 lower[j] = corner_points[i][j];
00634 if ( upper[j] < corner_points[i][j] )
00635 upper[j] = corner_points[i][j];
00636 }
00637 }
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654 int max_num_intervals = 1;
00655 for ( unsigned int i=0; i < dimension-1; ++i )
00656 max_num_intervals *= (int)vcl_floor( upper[i] - lower[i] + 1 );
00657
00658
00659
00660
00661
00662
00663
00664 vcl_vector< vnl_vector<double> > interval_indices;
00665 interval_indices.reserve( max_num_intervals );
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 interval_indices.push_back( center );
00681
00682 for ( unsigned int i=0; i < dimension-1; ++i )
00683 {
00684
00685
00686
00687 int lower_index = (int)vcl_ceil( lower[i] );
00688 int upper_index = (int)vcl_floor( upper[i] );
00689 int prev_size = interval_indices.size();
00690
00691
00692
00693
00694 for ( int prev=0; prev < prev_size; ++prev )
00695 {
00696 vnl_vector< double > partial_interval = interval_indices[prev];
00697 interval_indices[ prev ][ i ] = double(lower_index);
00698 for ( int index = lower_index + 1; index <= upper_index; ++index )
00699 {
00700 partial_interval[ i ] = double(index);
00701 interval_indices.push_back( partial_interval );
00702 }
00703 }
00704 }
00705
00706
00707
00708
00709
00710
00711 for ( unsigned int i=0; i < interval_indices . size(); ++i )
00712 {
00713 vnl_vector<double> & interval = interval_indices[i];
00714
00715
00716
00717 double min_z = lower[ dimension-1 ], max_z = upper[ dimension-1 ];
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 for ( unsigned int basis_index=0; basis_index<dimension; ++basis_index )
00729 {
00730
00731 vnl_vector< double > bdir =
00732 ( basis_dirs[ basis_index ][ dimension - 1 ] < 0 ) ?
00733 basis_dirs[ basis_index ] / -1 : basis_dirs[ basis_index ];
00734 double bradius = basis_radii[ basis_index ];
00735
00736
00737
00738
00739
00740
00741 if ( vnl_math_abs( bdir[ dimension-1 ] ) <= 1.0E-6 ) continue;
00742
00743
00744
00745
00746 double projection = dot_product( interval - center, bdir );
00747
00748
00749
00750
00751
00752 double basis_min_end = ( -bradius - projection ) / bdir[ dimension-1 ] + center[ dimension - 1 ] ;
00753 if ( min_z < basis_min_end ) min_z = basis_min_end;
00754 double basis_max_end = ( bradius - projection ) / bdir[ dimension-1 ] + center[ dimension - 1 ] ;
00755 if ( max_z > basis_max_end ) max_z = basis_max_end;
00756 }
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 vnl_vector< int > pixel_index( dimension, 0 );
00767
00768 for ( unsigned int d=0; d<dimension-1; ++d ) {
00769 pixel_index[d] = (int)interval[d] ;
00770 assert( pixel_index[ d ] == interval[ d ] );
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780 int last_lower_bound = (int)vcl_ceil( min_z );
00781 int last_upper_bound = (int)vcl_floor( max_z );
00782 for ( int last_component = last_lower_bound; last_component <= last_upper_bound;
00783 ++ last_component )
00784 {
00785 pixel_index[ dimension - 1 ] = last_component;
00786 pixel_locations.push_back( pixel_index );
00787 }
00788 }
00789 }
00790
00791 bool
00792 rgrl_util_irls( rgrl_match_set_sptr match_set,
00793 rgrl_scale_sptr scale,
00794 rgrl_weighter_sptr weighter,
00795 rgrl_convergence_tester const& conv_tester,
00796 rgrl_estimator_sptr estimator,
00797 rgrl_transformation_sptr & estimate,
00798 const bool fast_remapping,
00799 unsigned int debug_flag )
00800 {
00801 rgrl_set_of<rgrl_match_set_sptr> match_sets;
00802 match_sets.push_back( match_set );
00803 rgrl_set_of<rgrl_scale_sptr> scales;
00804 scales.push_back( scale );
00805 vcl_vector<rgrl_weighter_sptr> weighters;
00806 weighters.push_back(weighter);
00807
00808 return rgrl_util_irls(match_sets, scales, weighters,
00809 conv_tester, estimator, estimate, false,
00810 debug_flag);
00811 }
00812
00813 bool
00814 rgrl_util_irls( rgrl_set_of<rgrl_match_set_sptr> const& match_sets,
00815 rgrl_set_of<rgrl_scale_sptr> const& scales,
00816 vcl_vector<rgrl_weighter_sptr> const& weighters,
00817 rgrl_convergence_tester const& conv_tester,
00818 rgrl_estimator_sptr estimator,
00819 rgrl_transformation_sptr& estimate,
00820 const bool fast_remapping,
00821 unsigned int debug_flag )
00822 {
00823 DebugFuncMacro( debug_flag, 1, " In irls for model "<<estimator->transformation_type().name()<<'\n' );
00824
00825 typedef rgrl_match_set::from_iterator from_iter;
00826 typedef from_iter::to_iterator to_iter;
00827
00828 unsigned int iteration = 0;
00829 unsigned int max_iterations = 25;
00830 bool failed = false;
00831 vnl_vector<double> scaling;
00832
00833
00834
00835 if( estimator->is_iterative_method() ) {
00836
00837 rgrl_nonlinear_estimator* nonlinear_est
00838 = dynamic_cast<rgrl_nonlinear_estimator*>( estimator.as_pointer() );
00839 if( nonlinear_est ) {
00840
00841
00842 nonlinear_est->set_rel_thres( conv_tester.rel_tol() / 10.0 );
00843
00844
00845 nonlinear_est->set_max_num_iter( 15 );
00846 }
00847 }
00848
00849
00850
00851
00852
00853
00854
00855
00856 rgrl_converge_status_sptr current_status = conv_tester.initialize_status( estimate, estimator, scales[0], false );
00857
00858 for ( unsigned ms=0; ms < match_sets.size(); ++ms ) {
00859 rgrl_match_set_sptr match_set = match_sets[ms];
00860 if ( match_set && match_set->from_size() > 0) {
00861
00862 match_set->remap_from_features( *estimate );
00863
00864 weighters[ms]->compute_weights( *scales[ms], *match_set );
00865 }
00866 }
00867 do {
00868
00869
00870 rgrl_transformation_sptr
00871 new_estimate = estimator->estimate(match_sets, *estimate);
00872 if ( !new_estimate ) {
00873 estimate = 0;
00874 DebugFuncMacro( debug_flag, 1, "*** irls failed!\n" );
00875 return failed;
00876 }
00877
00878
00879 if ( rgrl_util_geometric_scaling_factors( match_sets, scaling ) )
00880 new_estimate->set_scaling_factors( scaling );
00881 else {
00882
00883 new_estimate->set_scaling_factors( estimate->scaling_factors() );
00884 vcl_cout << "WARNING in " << __FILE__ << __LINE__ << "cannot compute scaling factors!!!" << vcl_endl;
00885 }
00886
00887
00888
00889 for ( unsigned ms=0; ms < match_sets.size(); ++ms ) {
00890 rgrl_match_set_sptr match_set = match_sets[ms];
00891 if ( match_set && match_set->from_size() > 0) {
00892
00893
00894
00895 if( fast_remapping )
00896 match_set->remap_only_location( *new_estimate );
00897 else
00898 match_set->remap_from_features( *new_estimate );
00899
00900 weighters[ms]->compute_weights( *scales[ms], *match_set );
00901 }
00902 }
00903
00904
00905
00906
00907 current_status = conv_tester.compute_status( current_status,
00908 new_estimate, estimator,
00909 match_sets, scales, false);
00910
00911 DebugFuncMacro_abv(debug_flag, 2, "irls: (iteration = " << iteration
00912 << ") oscillation count = " << current_status->oscillation_count() << '\n' );
00913 DebugFuncMacro_abv(debug_flag, 2, "irls: error = " << current_status->error() << vcl_endl );
00914 DebugFuncMacro_abv(debug_flag, 2, "irls: error_diff = " << current_status->error_diff() << vcl_endl );
00915 DebugFuncMacro_abv(debug_flag, 2, "irls: converged = " << current_status->has_converged() << vcl_endl );
00916
00917 estimate = new_estimate;
00918 ++ iteration;
00919 } while ( !current_status->has_converged() &&
00920 !current_status->has_stagnated() &&
00921 !current_status->is_failed() &&
00922 iteration < max_iterations );
00923
00924 DebugFuncMacro_abv(debug_flag, 1, "irls status: " <<
00925 ( current_status->has_converged() ?
00926 "converged\n" : current_status->has_stagnated() ?
00927 "stagnated\n" : current_status->is_failed() ?
00928 "failed\n" :"reaches max iteration\n" ) );
00929
00930
00931
00932 if( fast_remapping )
00933 for ( unsigned ms=0; ms < match_sets.size(); ++ms ) {
00934
00935 rgrl_match_set_sptr match_set = match_sets[ms];
00936 if ( match_set && match_set->from_size() ) {
00937
00938 match_set->remap_from_features( *estimate );
00939 }
00940 }
00941
00942 return !failed;
00943 }
00944
00945
00946 void
00947 rgrl_util_skip_empty_lines( vcl_istream& is )
00948 {
00949 vcl_streampos pos;
00950 vcl_string str;
00951 static const vcl_string white_chars = " \t\r";
00952 vcl_string::size_type non_empty_pos;
00953
00954
00955 do {
00956
00957 pos = is.tellg();
00958 str = "";
00959 vcl_getline( is, str );
00960
00961 non_empty_pos = str.find_first_not_of( white_chars );
00962 } while ( is.good() && !is.eof() && (str.empty() || non_empty_pos == std::string::npos ||
00963 (str[non_empty_pos]=='#') ) );
00964
00965
00966 is.seekg( pos );
00967 }