00001 #ifndef rgrl_matcher_pseudo_txx_
00002 #define rgrl_matcher_pseudo_txx_
00003
00004 #include "rgrl_matcher_pseudo.h"
00005 #include <rgrl/rgrl_feature_face_region.h>
00006 #include <rgrl/rgrl_feature_trace_region.h>
00007 #include <rgrl/rgrl_feature_point_region.h>
00008 #include <rgrl/rgrl_match_set.h>
00009 #include <rgrl/rgrl_cast.h>
00010 #include <rgrl/rgrl_macros.h>
00011 #include <vnl/vnl_matrix.h>
00012 #include <vnl/vnl_math.h>
00013 #include <vnl/vnl_inverse.h>
00014 #include <vil/vil_bilin_interp.h>
00015 #include <vcl_cassert.h>
00016
00017 static const unsigned int verbose_ = 2;
00018 static const double rgrl_matcher_pseudo_max_response_value = 1.0e30;
00019
00020
00021 template <class PixelType>
00022 inline bool
00023 in_range( vil_image_view< PixelType > const& image,
00024 rgrl_mask_sptr const& mask,
00025 vnl_double_2 const& location )
00026 {
00027 if ( mask && !mask->inside( location.as_ref() ) )
00028 return false;
00029
00030 if ( location[ 0 ] < 0 || location[ 0 ] > image.ni()-1 ||
00031 location[ 1 ] < 0 || location[ 1 ] > image.nj()-1 )
00032 return false;
00033
00034 return true;
00035 }
00036
00037 template <class PixelType>
00038 inline bool
00039 in_range( vil_image_view< PixelType > const& image,
00040 rgrl_mask_sptr const& mask,
00041 vnl_vector< double > const& location )
00042 {
00043 if ( mask && !mask->inside( location ) )
00044 return false;
00045
00046 return true;
00047 }
00048
00049 template <class PixelType>
00050 rgrl_matcher_pseudo< PixelType > ::
00051 rgrl_matcher_pseudo( vil_image_view<PixelType> from_image,
00052 vil_image_view<PixelType> to_image,
00053 rgrl_evaluator_sptr evaluator,
00054 rgrl_mask_sptr from_mask,
00055 rgrl_mask_sptr to_mask )
00056 : from_image_( from_image ),
00057 to_image_( to_image ),
00058 from_mask_( from_mask ),
00059 to_mask_ ( to_mask ),
00060 evaluator_( evaluator )
00061 {}
00062
00063
00064 template <class PixelType>
00065 rgrl_match_set_sptr
00066 rgrl_matcher_pseudo< PixelType > ::
00067 compute_matches( rgrl_feature_set const& from_set,
00068 rgrl_feature_set const& to_set,
00069 rgrl_view const& current_view,
00070 rgrl_transformation const& current_xform,
00071 rgrl_scale const& current_scale,
00072 rgrl_match_set_sptr const& )
00073 {
00074 typedef vcl_vector<rgrl_feature_sptr> f_vector_type;
00075 typedef f_vector_type::iterator f_iterator_type;
00076
00077
00078 rgrl_match_set_sptr matches_sptr
00079 = new rgrl_match_set( from_set.type(), to_set.type(), from_set.label(), to_set.label() );
00080
00081
00082 f_vector_type from;
00083 from_set.features_in_region( from, current_view.region() );
00084 DebugMacro (1, " compute_matches : from.size() = " << from.size() << '\n' );
00085 DebugMacro_abv(1,"geometric scale = " << current_scale.geometric_scale()<< '\n' );
00086
00087
00088 rgrl_mapped_pixel_vector_type mapped_pixels;
00089 mapped_pixels.reserve( from.size() );
00090
00091
00092 f_vector_type matched_to_features;
00093 vcl_vector<double> match_weights;
00094
00095
00096 for ( f_iterator_type fitr = from.begin(); fitr != from.end(); ++fitr )
00097 {
00098
00099
00100
00101 matched_to_features.clear();
00102 match_weights.clear();
00103
00104
00105
00106
00107
00108
00109 rgrl_feature_sptr mapped_feature = (*fitr)->transform( current_xform );
00110
00111 {
00112 if ( (*fitr)->is_type( rgrl_feature_trace_region::type_id() ) )
00113 DebugMacro_abv(1, "\n\nfrom :\n" << (*fitr)->location() << " normal: "
00114 << rgrl_cast<rgrl_feature_trace_region *> ( *fitr )->normal_subspace().get_column(0)
00115 << "\nmapped :\n" << mapped_feature->location()
00116 << rgrl_cast<rgrl_feature_trace_region *> ( mapped_feature )->normal_subspace().get_column(0) <<'\n' );
00117 else if ( (*fitr)->is_type( rgrl_feature_face_region::type_id() ) )
00118 DebugMacro_abv(1, "\n\nfrom :\n" << (*fitr)->location() << " normal: "
00119 << rgrl_cast<rgrl_feature_face_region *> ( *fitr )->normal()
00120 << "\nmapped :\n" << mapped_feature->location() << " normal: "
00121 << rgrl_cast<rgrl_feature_face_region *> ( mapped_feature )->normal()<<'\n');
00122 else if ( (*fitr)->is_type( rgrl_feature_point_region::type_id() ) )
00123 DebugMacro_abv(1, "\n\nfrom :\n" << (*fitr)->location()
00124 << "\nmapped :\n" << mapped_feature->location()<<'\n');
00125 }
00126
00127
00128
00129
00130 if ( !in_range( to_image_, to_mask_, mapped_feature->location() ) ) {
00131
00132
00133 vcl_vector< double > match_weights( 0 );
00134
00135
00136 matches_sptr
00137 -> add_feature_matches_and_weights( *fitr, mapped_feature, matched_to_features,
00138 match_weights );
00139
00140 DebugMacro_abv(1, " skip match from: " << (*fitr)->location()
00141 << ", to: " << mapped_feature->location() << '\n' );
00142
00143 continue;
00144 }
00145
00146
00147
00148
00149
00150 mapped_pixels.clear();
00151
00152 this -> map_region_intensities( current_xform, (*fitr), mapped_pixels );
00153
00154
00155 if ( mapped_pixels.size() == 0 ) {
00156
00157
00158 vcl_vector< double > match_weights( 0 );
00159
00160
00161 matches_sptr
00162 -> add_feature_matches_and_weights( *fitr, mapped_feature, matched_to_features,
00163 match_weights );
00164 DebugMacro(3, " from point : " << (*fitr)->location()
00165 << " to point : " << mapped_feature->location() << " doesn't have proper matches\n");
00166 continue;
00167 }
00168
00169 this -> match_mapped_region( mapped_feature, mapped_pixels, current_scale,
00170 matched_to_features, match_weights );
00171
00172
00173
00174
00175
00176 matches_sptr -> add_feature_matches_and_weights( *fitr, mapped_feature, matched_to_features,
00177 match_weights );
00178 }
00179
00180 DebugMacro(3, "matches set from size = " << matches_sptr->from_size() <<'\n');
00181
00182 typedef rgrl_match_set::from_iterator from_iter;
00183 typedef from_iter::to_iterator to_iter;
00184 for ( from_iter fitr = matches_sptr->from_begin(); fitr != matches_sptr->from_end(); ++fitr ) {
00185 if ( fitr.size() == 0 ) continue;
00186
00187 rgrl_feature_sptr mapped_from = fitr.mapped_from_feature();
00188 for ( to_iter titr = fitr.begin(); titr != fitr.end(); ++titr ) {
00189 rgrl_feature_sptr to = titr.to_feature();
00190 DebugMacro(3, mapped_from->location()[0]<<' '<<mapped_from->location()[1]
00191 <<' '<< to->location()[0]<<' '<<to->location()[1]<<'\n');
00192 }
00193 }
00194
00195 return matches_sptr;
00196 }
00197
00198
00199 template <class PixelType>
00200 void
00201 rgrl_matcher_pseudo<PixelType> ::
00202 map_region_intensities( rgrl_transformation const& trans,
00203 rgrl_feature_sptr feature_sptr,
00204 rgrl_mapped_pixel_vector_type & mapped_pixels) const
00205 {
00206 static vnl_vector<double> spacing_ratio( 2, 1.0 );
00207
00208 if ( feature_sptr -> is_type( rgrl_feature_face_region::type_id() ) )
00209 {
00210 rgrl_feature_face_region * face_ptr =
00211 rgrl_cast<rgrl_feature_face_region *> ( feature_sptr );
00212 this -> map_region_intensities( face_ptr -> pixel_coordinates_ratio( spacing_ratio ), trans,
00213 feature_sptr, mapped_pixels );
00214 }
00215 else if ( feature_sptr -> is_type( rgrl_feature_trace_region::type_id() ))
00216 {
00217 rgrl_feature_trace_region * trace_ptr =
00218 rgrl_cast<rgrl_feature_trace_region *> ( feature_sptr );
00219 this -> map_region_intensities( trace_ptr -> pixel_coordinates_ratio( spacing_ratio ), trans,
00220 feature_sptr, mapped_pixels );
00221 }
00222 else
00223 {
00224 rgrl_feature_point_region * point_ptr =
00225 rgrl_cast<rgrl_feature_point_region *> ( feature_sptr );
00226 this -> map_region_intensities( point_ptr -> pixel_coordinates_ratio( spacing_ratio ), trans,
00227 feature_sptr, mapped_pixels );
00228 }
00229 }
00230
00231
00232 template <class PixelType>
00233 void
00234 rgrl_matcher_pseudo<PixelType> ::
00235 map_region_intensities( vcl_vector< vnl_vector<int> > const& pixel_locations,
00236 rgrl_transformation const& trans,
00237 rgrl_feature_sptr feature_sptr,
00238 rgrl_mapped_pixel_vector_type & mapped_pixels) const
00239 {
00240 DebugMacro(3," number of points around the from point: " << pixel_locations.size() <<'\n');
00241
00242 if ( pixel_locations.empty() ) return;
00243
00244 unsigned dim = feature_sptr -> location() . size();
00245 assert ( dim == 2 );
00246 vnl_double_2 pixel_loc_dbl;
00247 rgrl_mapped_pixel_type mapped_pixel;
00248 mapped_pixel . weight = 1.0;
00249
00250
00251 mapped_pixels.reserve( pixel_locations.size() );
00252
00253 double intensity;
00254 for ( unsigned int i=0; i<pixel_locations.size(); ++i )
00255 {
00256
00257 for ( unsigned int j=0; j<dim; ++j ) pixel_loc_dbl[j] = pixel_locations[i][j];
00258
00259 if ( !in_range( from_image_, from_mask_, pixel_loc_dbl ) )
00260 continue;
00261
00262 trans.map_location( pixel_loc_dbl.as_ref(), mapped_pixel.location.as_ref().non_const() );
00263
00264 if ( !in_range( to_image_, to_mask_, mapped_pixel.location ) )
00265 continue;
00266
00267
00268
00269 assert ( from_image_.nplanes() == 1 );
00270
00271 intensity = from_image_( pixel_locations[i][0], pixel_locations[i][1] );
00272
00273 mapped_pixel . intensity = intensity;
00274 mapped_pixels . push_back( mapped_pixel );
00275 }
00276 }
00277
00278 #if 0
00279 inline double
00280 est_sub_offset( vnl_matrix< double > const& A, vnl_matrix< double > const& S )
00281 {
00282
00283 vnl_matrix< double > inv = vnl_inverse(A);
00284 vnl_matrix< double > X = inv * S;
00285 assert( X.columns() == 1 );
00286
00287
00288
00289 if ( X[ 0 ][ 0 ] == 0 )
00290 return 0.0;
00291
00292
00293
00294
00295 return - X[ 1 ][ 0 ] / ( 2 * X[ 0 ][ 0 ] ) ;
00296 }
00297 #endif // 0
00298
00299 #if 0
00300 inline vnl_vector< double >
00301 sub_pixel_2d( vcl_vector< vcl_vector< double > > const& responses,
00302 int idx1, int idx2 )
00303 {
00304 assert( responses.size() >= 3 );
00305 assert( responses[ 0 ].size() >= 3 );
00306 for ( unsigned i = 1; i < responses.size(); ++i ) {
00307 assert( responses[ i ].size() == responses[ 0 ].size() );
00308 }
00309
00310 if ( idx1 == 0 ) idx1 = 1;
00311 if ( idx2 == 0 ) idx2 = 1;
00312
00313 if ( idx1 == (int)responses.size() - 1 )
00314 idx1 = responses.size() - 2;
00315 if ( idx2 == (int)responses.size() - 1 )
00316 idx2 = responses.size() - 2;
00317
00318
00319
00320
00321
00322
00323
00324
00325 vnl_matrix < double > A ( 3, 3 );
00326 vnl_matrix< double > S1 ( 3, 1 ) ;
00327 vnl_matrix< double > S2 ( 3, 1 ) ;
00328
00329 for ( int r = -1; r <= 1; ++r ) {
00330 A( r+1, 0 ) = r * r;
00331 A( r+1, 1 ) = r;
00332 A( r+1, 2 ) = 1;
00333 S1( r+1, 0 ) = responses[ idx1 + r][ idx2 ];
00334 S2( r+1, 0 ) = responses[ idx1 ][ idx2 + r ];
00335 }
00336
00337 vnl_vector< double > best_index( 2 );
00338 best_index[ 0 ] = est_sub_offset( A, S1 ) + idx1;
00339 best_index[ 1 ] = est_sub_offset( A, S2 ) + idx2;
00340
00341 return best_index;
00342 }
00343 #endif // 0
00344
00345 inline double
00346 rgrl_matcher_pseudo_sub_pixel( vcl_vector< double > const& responses )
00347 {
00348 assert( responses.size() == 3 );
00349
00350
00351
00352
00353 vnl_matrix < double > A ( 3, 3 );
00354 vnl_matrix< double > S ( 3, 1 ) ;
00355
00356 for ( unsigned i = 0; i < 3; ++i ) {
00357 int r = i - 1;
00358 A( r+1, 0 ) = r * r;
00359 A( r+1, 1 ) = r;
00360 A( r+1, 2 ) = 1;
00361 S( r+1, 0 ) = responses[ i ];
00362 }
00363
00364 vnl_matrix< double > inv = vnl_inverse(A);
00365 vnl_matrix< double > X = inv * S;
00366 assert( X.columns() == 1 );
00367
00368
00369
00370 if ( X[ 0 ][ 0 ] <= 1.0e-5 ) {
00371 return 0;
00372 }
00373
00374
00375
00376
00377 double best_index = -X[ 1 ][ 0 ] / ( 2 * X[ 0 ][ 0 ] );
00378
00379 assert( best_index <= 1 && best_index >= -1 );
00380
00381 return best_index;
00382 }
00383
00384 template <class PixelType>
00385 void
00386 rgrl_matcher_pseudo<PixelType> ::
00387 match_mapped_region( rgrl_feature_sptr mapped_feature,
00388 rgrl_mapped_pixel_vector_type const & mapped_pixels,
00389 rgrl_scale const & current_scale,
00390 vcl_vector< rgrl_feature_sptr > & matched_to_features,
00391 vcl_vector< double > & match_weights ) const
00392 {
00393
00394
00395 unsigned int dim = mapped_feature -> location() . size();
00396
00397 const double scale_multiplier = 4;
00398
00399 vnl_matrix< double > normal_space;
00400
00401 if ( mapped_feature -> is_type( rgrl_feature_face_region::type_id() ) )
00402 {
00403 rgrl_feature_face_region * face_ptr =
00404 rgrl_cast<rgrl_feature_face_region *> ( mapped_feature );
00405 normal_space = vnl_matrix< double > ( dim, 1 );
00406 normal_space . set_column ( 0, face_ptr -> normal() );
00407 }
00408 else if ( mapped_feature->is_type( rgrl_feature_trace_region::type_id()) )
00409 {
00410 rgrl_feature_trace_region * trace_ptr =
00411 rgrl_cast<rgrl_feature_trace_region *> ( mapped_feature );
00412 normal_space = trace_ptr -> normal_subspace();
00413 }
00414 else {
00415 normal_space = vnl_matrix<double>(2,2,vnl_matrix_identity);
00416 }
00417
00418 vnl_double_2 match_location;
00419 double min_response = 0.0;
00420 double second_derivative = 0.0;
00421 int max_offset = vnl_math_rnd( scale_multiplier * current_scale . geometric_scale() );
00422 if ( max_offset == 0 ) max_offset = 1;
00423
00424
00425
00426
00427
00428
00429
00430 if ( normal_space.columns() == 1 ) {
00431 vnl_double_2 basis = normal_space.get_column(0);
00432
00433 DebugMacro_abv(2, "normal basis :\n" << basis << '\n');
00434
00435 vcl_vector<double> responses( 2*max_offset+1, 0.0 );
00436 bool is_best_initialized = false;
00437 int best_offset = 0;
00438
00439
00440
00441
00442 vnl_double_2 mapped_location = mapped_feature -> location();
00443
00444
00445
00446 for ( int abs_offset = 0; abs_offset <= max_offset; ++abs_offset )
00447 {
00448 int offset = abs_offset;
00449 do {
00450 int i = offset + max_offset;
00451 responses[i] = this -> compute_response( mapped_location, mapped_pixels, basis * double(offset) );
00452
00453 DebugMacro_abv(2," response at offset " << offset
00454 << " ( i = " << i << " ) : " << responses[ i ] <<'\n' );
00455
00456
00457
00458 if ( (!is_best_initialized || responses[i] < min_response ) &&
00459 responses[ i ] != rgrl_matcher_pseudo_max_response_value )
00460 {
00461 is_best_initialized = true;
00462 min_response = responses[i];
00463 best_offset = offset;
00464 }
00465 offset = -offset;
00466 } while ( offset < 0 );
00467 }
00468
00469 DebugMacro_abv(2," the best offset = " << best_offset << '\n' );
00470
00471 assert( is_best_initialized );
00472
00473
00474
00475
00476 int deriv_loc = best_offset;
00477 if ( deriv_loc == -max_offset ) ++ deriv_loc;
00478 else if ( deriv_loc == max_offset ) -- deriv_loc;
00479 int index = deriv_loc + max_offset;
00480
00481
00482
00483
00484
00485
00486
00487 double sub_offset = 0;
00488 if ( best_offset != max_offset &&
00489 best_offset != -max_offset )
00490 {
00491
00492
00493 if ( responses[ index - 1 ] == rgrl_matcher_pseudo_max_response_value )
00494 index ++;
00495 else if ( responses[ index + 1 ] == rgrl_matcher_pseudo_max_response_value )
00496 index--;
00497 else
00498 {
00499 vcl_vector< double > responses_for_sub_pixel( 3 );
00500 responses_for_sub_pixel[ 0 ] = responses[ index - 1 ];
00501 responses_for_sub_pixel[ 1 ] = responses[ index ];
00502 responses_for_sub_pixel[ 2 ] = responses[ index + 1 ];
00503 sub_offset = rgrl_matcher_pseudo_sub_pixel( responses_for_sub_pixel );
00504 assert( sub_offset + best_offset >= -max_offset );
00505 assert( sub_offset + best_offset <= max_offset );
00506
00507
00508 }
00509 }
00510
00511 match_location = mapped_location + basis * ( best_offset + sub_offset );
00512
00513 DebugMacro_abv(2,"best match :\n" << match_location << '\n' );
00514
00515
00516
00517
00518
00519 if ( index >0 && index+1 < (int)responses.size() &&
00520 responses[ index ] != rgrl_matcher_pseudo_max_response_value &&
00521 index + 1 <= 2*max_offset &&
00522 index - 1 >= -2*max_offset &&
00523 responses[ index + 1 ] != rgrl_matcher_pseudo_max_response_value &&
00524 responses[ index - 1 ] != rgrl_matcher_pseudo_max_response_value )
00525 second_derivative = vnl_math_abs( responses[ index-1 ] + responses[ index+1 ]
00526 - 2 * responses[ index ] );
00527
00528
00529 else {
00530 second_derivative = 0;
00531 DebugMacro_abv(2, "index=" << index << ", max_offset="
00532 << max_offset << ", responses[index-1]=" << responses[index-1]
00533 << ", responses[index+1]=" << responses[index+1] << '\n'
00534 << " neighbors' responses are not valid. Set the second_derivative = 0\n");
00535 }
00536 }
00537 else if ( normal_space.columns() == 2 ) {
00538 vnl_vector<double> basis1 = normal_space . get_column(0);
00539 vnl_vector<double> basis2 = normal_space . get_column(1);
00540
00541 vcl_vector<double> temp( 2*max_offset+1, 0.0 );
00542 vcl_vector< vcl_vector<double> > responses( 2*max_offset+1, temp );
00543
00544 bool is_best_initialized = false;
00545 int best_off1 = 0, best_off2 = 0;
00546
00547
00548
00549
00550 vnl_vector<double> mapped_location = mapped_feature -> location();
00551 for ( int off1 = -max_offset, i=0; off1 <= max_offset; ++off1, ++i )
00552 for ( int off2 = -max_offset, j=0; off2 <= max_offset; ++off2, ++j )
00553 {
00554 responses[i][j] = this -> compute_response( mapped_location, mapped_pixels,
00555 basis1 * off1 + basis2 * off2 );
00556
00557 if ( ( !is_best_initialized || responses[i][j] < min_response )
00558 && responses[i][j] != rgrl_matcher_pseudo_max_response_value )
00559 {
00560 is_best_initialized = true;
00561 min_response = responses[i][j];
00562 best_off1 = off1;
00563 best_off2 = off2;
00564 }
00565 }
00566
00567 assert( is_best_initialized );
00568
00569
00570
00571
00572
00573 int deriv_loc1 = best_off1;
00574 if ( deriv_loc1 == -max_offset ) ++deriv_loc1;
00575 else if ( deriv_loc1 == max_offset ) --deriv_loc1;
00576 int idx1 = deriv_loc1 + max_offset;
00577 int idx2 = best_off2 + max_offset;
00578
00579
00580
00581
00582
00583
00584
00585 double sub_offset1;
00586
00587 if ( best_off1 == max_offset || best_off1 == -max_offset )
00588 sub_offset1 = best_off1;
00589 else if ( responses[ idx1 - 1 ][ idx2 ] == rgrl_matcher_pseudo_max_response_value ||
00590 responses[ idx1 + 1 ][ idx2 ] == rgrl_matcher_pseudo_max_response_value )
00591 {
00592 sub_offset1 = idx1 - max_offset;
00593 }
00594 else
00595 {
00596 vcl_vector< double > responses_for_sub_pixel( 3 );
00597 responses_for_sub_pixel[ 0 ] = responses[ idx1 - 1 ][ idx2 ];
00598 responses_for_sub_pixel[ 1 ] = responses[ idx1 ][ idx2 ];
00599 responses_for_sub_pixel[ 2 ] = responses[ idx1 + 1 ][ idx2 ];
00600 sub_offset1 = rgrl_matcher_pseudo_sub_pixel( responses_for_sub_pixel ) + idx1 - max_offset;
00601
00602
00603 if ( sub_offset1 < -max_offset ) sub_offset1 = -max_offset;
00604 if ( sub_offset1 > max_offset ) sub_offset1 = max_offset;
00605 DebugMacro_abv(2, " sub_offset1 = " << sub_offset1 << " in [ "
00606 << -max_offset << " , " << max_offset << " ]\n");
00607 }
00608
00609 double second_d1 = vnl_math_abs( responses[ idx1-1 ][ idx2 ] + responses[ idx1+1 ][ idx2 ]
00610 - 2 * responses[ idx1 ][ idx2 ] );
00611
00612 int deriv_loc2 = best_off2;
00613 if ( deriv_loc2 == -max_offset ) ++deriv_loc2;
00614 else if ( deriv_loc2 == max_offset ) --deriv_loc2;
00615 idx2 = deriv_loc2 + max_offset;
00616 idx1 = best_off1 + max_offset;
00617 double sub_offset2;
00618 if ( best_off2 == max_offset || best_off2 == -max_offset )
00619 sub_offset2 = best_off2;
00620 else if ( responses[ idx1 ][ idx2 - 1 ] == rgrl_matcher_pseudo_max_response_value ||
00621 responses[ idx1 ][ idx2 + 1 ] == rgrl_matcher_pseudo_max_response_value )
00622 {
00623 sub_offset2 = idx2 - max_offset;
00624 }
00625 else
00626 {
00627 vcl_vector< double > responses_for_sub_pixel( 3 );
00628 responses_for_sub_pixel[ 0 ] = responses[ idx1 ][ idx2 - 1 ];
00629 responses_for_sub_pixel[ 1 ] = responses[ idx1 ][ idx2 ];
00630 responses_for_sub_pixel[ 2 ] = responses[ idx1 ][ idx2 + 1 ];
00631 sub_offset2 = rgrl_matcher_pseudo_sub_pixel( responses_for_sub_pixel ) + idx2 - max_offset;
00632 if ( sub_offset2 < -max_offset ) sub_offset2 = -max_offset;
00633 if ( sub_offset2 > max_offset ) sub_offset2 = max_offset;
00634
00635 DebugMacro_abv(2, " sub_offset2 = " << sub_offset2 << " in [ "
00636 << -max_offset << " , " << max_offset << " ]\n");
00637 }
00638
00639 double second_d2 = vnl_math_abs( responses[ idx1 ][ idx2-1 ] + responses[ idx1 ][ idx2+1 ]
00640 - 2 * responses[ idx1 ][ idx2 ] );
00641
00642 second_derivative = vnl_math_min( second_d1, second_d2 );
00643 match_location = mapped_location + basis1 * sub_offset1 + basis2 * sub_offset2;
00644 DebugMacro_abv(1, "best match :\n" << match_location << '\n' );
00645 }
00646 else {
00647 vcl_cerr << "Code doesn't handle a normal subspace of greater than two dimenions.\n";
00648 assert( false );
00649 }
00650
00651 matched_to_features . clear();
00652 match_weights . clear();
00653 rgrl_feature_sptr mf_ptr;
00654 if ( mapped_feature -> is_type( rgrl_feature_face_region::type_id() ) )
00655 {
00656 rgrl_feature_face_region * face_ptr =
00657 rgrl_cast<rgrl_feature_face_region *> ( mapped_feature );
00658 mf_ptr = new rgrl_feature_face_region( match_location.as_ref(), face_ptr -> normal() );
00659 }
00660 else if ( mapped_feature -> is_type( rgrl_feature_trace_region::type_id() ) )
00661 {
00662 rgrl_feature_trace_region * trace_ptr =
00663 rgrl_cast<rgrl_feature_trace_region *> ( mapped_feature );
00664 mf_ptr = new rgrl_feature_trace_region( match_location.as_ref(), trace_ptr -> tangent() );
00665 }
00666 else {
00667 mf_ptr = new rgrl_feature_point_region( match_location.as_ref() );
00668 }
00669
00670 matched_to_features.push_back( mf_ptr );
00671 double weight = second_derivative / (1.0 + min_response);
00672 #if 0 // other options for weights
00673 double epsilon = 1e-16;
00674 double weight = min_response/(second_derivative + epsilon);
00675 double weight = 1;
00676 #endif // 0
00677
00678 match_weights.push_back( weight );
00679 DebugMacro(3, "Signature error for best match :\n" << weight
00680 << ", second_derivative = "<< second_derivative
00681 << " min_response = "<<min_response
00682 << " old wgt = "<<second_derivative / (1.0 + min_response)<<'\n');
00683 }
00684
00685 template <class PixelType>
00686 double
00687 rgrl_matcher_pseudo<PixelType> ::
00688 compute_response( vnl_double_2 const& mapped_location,
00689 rgrl_mapped_pixel_vector_type const& mapped_pixels,
00690 vnl_double_2 const& shift ) const
00691 {
00692
00693
00694
00695 vcl_vector< double > a;
00696 vcl_vector< double > b;
00697 vcl_vector< double > weights;
00698 double intensity;
00699
00700
00701 a.reserve( mapped_pixels.size() );
00702 b.reserve( mapped_pixels.size() );
00703 weights.reserve( mapped_pixels.size() );
00704 for ( unsigned i = 0; i < mapped_pixels.size(); ++i ) {
00705 vnl_double_2 location = mapped_pixels[i].location + shift;
00706
00707
00708 if ( !in_range( to_image_, to_mask_, location ) )
00709 return rgrl_matcher_pseudo_max_response_value;
00710
00711 intensity = vil_bilin_interp(to_image_, location[0], location[1] );
00712 a.push_back( (double)(mapped_pixels[i].intensity) );
00713 b.push_back( intensity );
00714 weights.push_back( mapped_pixels[i].weight );
00715 }
00716
00717
00718 return evaluator_->evaluate( a, b, weights );
00719 }
00720
00721 #endif // rgrl_matcher_pseudo_txx_