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