Go to the documentation of this file.00001 #include "rgrl_matcher_k_nearest_adv.h"
00002
00003
00004
00005
00006
00007 #include <rgrl/rgrl_feature.h>
00008 #include <rgrl/rgrl_feature_set.h>
00009 #include <rgrl/rgrl_transformation.h>
00010 #include <rgrl/rgrl_view.h>
00011 #include <rgrl/rgrl_match_set.h>
00012
00013 #include <vcl_map.h>
00014 #include <vcl_cassert.h>
00015
00016
00017
00018 struct feature_sptr_iterator_pair {
00019
00020 typedef rgrl_match_set::const_from_iterator from_feature_iterator;
00021 rgrl_feature_sptr feature_;
00022 from_feature_iterator fea_iterator_;
00023
00024 feature_sptr_iterator_pair()
00025 { }
00026
00027 feature_sptr_iterator_pair( rgrl_feature_sptr const& fea, from_feature_iterator const& it )
00028 : feature_( fea), fea_iterator_( it )
00029 { }
00030
00031 bool operator< ( feature_sptr_iterator_pair const& rhs ) const
00032 { return this->feature_ < rhs.feature_; }
00033
00034 bool operator== ( feature_sptr_iterator_pair const& rhs ) const
00035 { return this->feature_ == rhs.feature_; }
00036 };
00037
00038 rgrl_matcher_k_nearest_adv::
00039 rgrl_matcher_k_nearest_adv( unsigned int k )
00040 : rgrl_matcher_k_nearest(k),
00041 min_mapped_scale_( -1 ),
00042 sqr_thres_for_reuse_match_( -1 )
00043 {
00044 }
00045
00046
00047 rgrl_matcher_k_nearest_adv::
00048 rgrl_matcher_k_nearest_adv( unsigned int k, double dist_thres, double min_mapped_scale, double thres_reuse_match )
00049 : rgrl_matcher_k_nearest( k, dist_thres ),
00050 min_mapped_scale_( min_mapped_scale ),
00051 sqr_thres_for_reuse_match_( thres_reuse_match )
00052 {
00053 if ( sqr_thres_for_reuse_match_ > 0 )
00054 sqr_thres_for_reuse_match_ = sqr_thres_for_reuse_match_*sqr_thres_for_reuse_match_;
00055 }
00056
00057
00058 rgrl_match_set_sptr
00059 rgrl_matcher_k_nearest_adv::
00060 compute_matches( rgrl_feature_set const& from_set,
00061 rgrl_feature_set const& to_set,
00062 rgrl_view const& current_view,
00063 rgrl_transformation const& current_xform,
00064 rgrl_scale const& ,
00065 rgrl_match_set_sptr const& old_matches )
00066 {
00067 typedef rgrl_view::feature_vector feat_vector;
00068 typedef feat_vector::const_iterator feat_iter;
00069
00070 assert( current_view.xform_estimate().as_pointer() == ¤t_xform );
00071
00072
00073 const bool allow_reuse_match = ( sqr_thres_for_reuse_match_ > 0) && (prev_xform_) && (old_matches);
00074
00075
00076
00077 typedef rgrl_match_set::const_from_iterator from_feature_iterator;
00078 vcl_map< rgrl_feature_sptr, from_feature_iterator > feature_sptr_iterator_map;
00079 if ( allow_reuse_match )
00080 {
00081 for ( from_feature_iterator i=old_matches->from_begin(); i!=old_matches->from_end(); ++i )
00082 feature_sptr_iterator_map[ i.from_feature() ] = i;
00083 }
00084
00085
00086
00087 rgrl_match_set_sptr matches_sptr
00088 = new rgrl_match_set( from_set.type(), to_set.type(), from_set.label(), to_set.label() );
00089
00090
00091 feat_vector from;
00092 if ( !current_view.features_in_region( from, from_set ) ) {
00093 DebugMacro( 1, "Cannot get features in current region!!!\n");
00094 return matches_sptr;
00095 }
00096
00097
00098 feat_vector matching_features, pruned_set;
00099 matching_features.reserve( 10 );
00100 pruned_set.reserve( 10 );
00101
00102 matches_sptr->reserve( from.size() );
00103
00104
00105 vnl_vector<double> prev_mapped;
00106 int reuse_match_count = 0;
00107 for ( feat_iter fitr = from.begin(); fitr != from.end(); ++fitr )
00108 {
00109 rgrl_feature_sptr mapped = (*fitr)->transform( current_xform );
00110 if ( !validate( mapped, current_view.to_image_roi() ) )
00111 continue;
00112
00113 matching_features.clear();
00114
00115 if ( allow_reuse_match )
00116 {
00117 prev_xform_->map_location( (*fitr)->location(), prev_mapped );
00118
00119
00120 vcl_map< rgrl_feature_sptr, from_feature_iterator >::const_iterator map_itr;
00121 if ( vnl_vector_ssd( prev_mapped, mapped->location() ) < sqr_thres_for_reuse_match_ &&
00122 (map_itr=feature_sptr_iterator_map.find( *fitr )) != feature_sptr_iterator_map.end() )
00123 {
00124
00125 const from_feature_iterator& prev_from_iter = map_itr->second;
00126 for ( from_feature_iterator::to_iterator titr=prev_from_iter.begin(); titr!=prev_from_iter.end(); ++titr )
00127 matching_features.push_back( titr.to_feature() );
00128
00129
00130 ++reuse_match_count;
00131 }
00132 else
00133 to_set.k_nearest_features( matching_features, mapped, k_ );
00134 }
00135 else
00136 to_set.k_nearest_features( matching_features, mapped, k_ );
00137
00138
00139
00140 if ( thres_ > 0 ) {
00141 pruned_set.clear();
00142 for ( feat_iter i = matching_features.begin(); i != matching_features.end(); ++i ) {
00143 if ( vnl_vector_ssd( (*i)->location(), mapped->location() ) < thres_ ) {
00144 pruned_set.push_back( *i );
00145 }
00146 }
00147 if ( !pruned_set.empty() ) {
00148 matches_sptr->add_feature_and_matches( *fitr, mapped,
00149 pruned_set );
00150 }
00151 } else {
00152 matches_sptr->add_feature_and_matches( *fitr, mapped,
00153 matching_features );
00154 }
00155 }
00156
00157 DebugMacro( 1, "There are " << reuse_match_count << " reuse of previous matches out of " << from.size() << vcl_endl );
00158
00159
00160 prev_xform_ = current_view.xform_estimate();
00161
00162 return matches_sptr;
00163 }
00164
00165 inline
00166 bool
00167 rgrl_matcher_k_nearest_adv::
00168 validate( rgrl_feature_sptr const& mapped, rgrl_mask_sptr const& roi_sptr ) const
00169 {
00170
00171 if ( !roi_sptr->inside( mapped->location() ) )
00172 return false;
00173
00174
00175
00176
00177
00178
00179
00180
00181 const double scale = mapped->scale();
00182 if ( scale!=0 && min_mapped_scale_>0 && scale<min_mapped_scale_ ) {
00183 return false;
00184 }
00185
00186
00187 return true;
00188 }