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