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