contrib/rpl/rgrl/rgrl_matcher_k_nearest_random.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \author Gehua Yang
00004 // \date   March 2005
00005 #include "rgrl_matcher_k_nearest_random.h"
00006 #include <rgrl/rgrl_feature.h>
00007 #include <rgrl/rgrl_feature_set.h>
00008 #include <rgrl/rgrl_transformation.h>
00009 #include <rgrl/rgrl_view.h>
00010 #include <rgrl/rgrl_match_set.h>
00011 
00012 #include <vcl_vector.h>
00013 #include <vcl_algorithm.h>
00014 
00015 rgrl_matcher_k_nearest_random::
00016 rgrl_matcher_k_nearest_random( unsigned int k, unsigned int max_num )
00017   : rgrl_matcher_k_nearest( k ),
00018     max_num_( max_num )
00019 {
00020 }
00021 
00022 
00023 rgrl_matcher_k_nearest_random::
00024 rgrl_matcher_k_nearest_random( unsigned int k, unsigned int max_num, double dist_thres )
00025   : rgrl_matcher_k_nearest( k, dist_thres ),
00026     max_num_( max_num )
00027 {
00028 }
00029 
00030 
00031 rgrl_match_set_sptr
00032 rgrl_matcher_k_nearest_random::
00033 compute_matches( rgrl_feature_set const&       from_set,
00034                  rgrl_feature_set const&       to_set,
00035                  rgrl_view const&              current_view,
00036                  rgrl_transformation const&    current_xform,
00037                  rgrl_scale const&             /* current_scale */,
00038                  rgrl_match_set_sptr const&    /*old_matches*/ )
00039 {
00040   typedef rgrl_view::feature_vector feat_vector;
00041   typedef feat_vector::const_iterator feat_iter;
00042 
00043   rgrl_match_set_sptr matches_sptr 
00044     = new rgrl_match_set( from_set.type(), to_set.type(), from_set.label(), to_set.label() );
00045 
00046   //  get the features in the current view
00047   feat_vector from;
00048   if( !current_view.features_in_region( from, from_set ) ) {
00049     DebugMacro( 1, "Cannot get features in current region!!!" << vcl_endl );
00050     return matches_sptr;
00051   }
00052 
00053   // reserve size
00054   feat_vector matching_features, pruned_set;
00055   matching_features.reserve( 10 );
00056   pruned_set.reserve( 10 );
00057 
00058   matches_sptr->reserve( from.size() );
00059 
00060   // set up a vector of same from size to indicate which feature shall be used
00061   vcl_vector<bool> to_use( from.size(), true );
00062   
00063   if( from.size() > max_num_ )
00064     generate_random_indices( to_use );
00065   
00066   //  generate the matches for each feature of this feature type in the current region
00067   unsigned int k;
00068   feat_iter fitr;
00069   for ( k=0, fitr = from.begin(); fitr != from.end(); ++fitr, ++k ) 
00070     if( to_use[k] ) {
00071 
00072     rgrl_feature_sptr mapped = (*fitr)->transform( current_xform );
00073     if( !validate( mapped, current_view.to_image_roi() ) )
00074       continue;   // feature is invalid
00075 
00076     matching_features.clear();
00077     to_set.k_nearest_features( matching_features, mapped, k_ );
00078 
00079     // prune the matches to satisfy the threshold
00080     //
00081     if ( thres_ > 0 ) {
00082       pruned_set.clear();
00083       for ( feat_iter i = matching_features.begin(); i != matching_features.end(); ++i ) {
00084         if ( vnl_vector_ssd( (*i)->location(), mapped->location() ) < thres_ ) {
00085           pruned_set.push_back( *i );
00086         }
00087       }
00088       if ( !pruned_set.empty() ) {
00089         matches_sptr->add_feature_and_matches( *fitr, mapped,
00090                                                pruned_set );
00091       }
00092     } else {
00093       matches_sptr->add_feature_and_matches( *fitr, mapped,
00094                                              matching_features );
00095     }
00096   }
00097 
00098   return matches_sptr;
00099 }
00100 
00101 void
00102 rgrl_matcher_k_nearest_random::
00103 generate_random_indices( vcl_vector<bool>& to_use ) const 
00104 {
00105   const unsigned size = to_use.size();
00106 
00107   // set all entries to false
00108   vcl_fill( to_use.begin(), to_use.end(), false );
00109     
00110   unsigned num = 0;
00111   while( num < max_num_ ) {
00112     
00113     unsigned index = random_.lrand32( size );
00114     // already marked?
00115     if( to_use[index] )
00116       continue;
00117     
00118     // mark it
00119     // vcl_cout << index << ' ';
00120     to_use[index] = true;
00121     ++num;
00122   }
00123   // vcl_cout <<"\n";
00124 }