Go to the documentation of this file.00001 #include "rgrl_matcher_k_nearest_pick_one.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 #include <vcl_vector.h>
00013 #include <vcl_algorithm.h>
00014
00015
00016 rgrl_matcher_k_nearest_pick_one::
00017 rgrl_matcher_k_nearest_pick_one( unsigned int k )
00018 : rgrl_matcher_k_nearest_adv( k )
00019 {
00020 }
00021
00022
00023 rgrl_matcher_k_nearest_pick_one::
00024 rgrl_matcher_k_nearest_pick_one( unsigned int k, double dist_thres, double min_mapped_scale, double thres_reuse_match )
00025 : rgrl_matcher_k_nearest_adv(k, dist_thres, min_mapped_scale, thres_reuse_match)
00026 {
00027 }
00028
00029
00030 rgrl_match_set_sptr
00031 rgrl_matcher_k_nearest_pick_one::
00032 compute_matches( rgrl_feature_set const& from_set,
00033 rgrl_feature_set const& to_set,
00034 rgrl_view const& current_view,
00035 rgrl_transformation const& current_xform,
00036 rgrl_scale const& ,
00037 rgrl_match_set_sptr const& old_matches )
00038 {
00039 typedef rgrl_view::feature_vector feat_vector;
00040 typedef feat_vector::const_iterator feat_iter;
00041
00042 DebugMacro( 2, "Compute matches between features "
00043 << from_set.label().name() << "-->"
00044 << to_set.label().name() << vcl_endl; );
00045
00046
00047 const bool allow_reuse_match = ( sqr_thres_for_reuse_match_ > 0) && (prev_xform_) && (old_matches);
00048
00049
00050
00051 typedef rgrl_match_set::const_from_iterator from_feature_iterator;
00052 vcl_map< rgrl_feature_sptr, from_feature_iterator > feature_sptr_iterator_map;
00053 if ( allow_reuse_match )
00054 {
00055 for ( from_feature_iterator i=old_matches->from_begin(); i!=old_matches->from_end(); ++i )
00056 feature_sptr_iterator_map[ i.from_feature() ] = i;
00057 }
00058
00059
00060
00061 rgrl_match_set_sptr matches_sptr
00062 = new rgrl_match_set( from_set.type(), to_set.type(), from_set.label(), to_set.label() );
00063
00064
00065 feat_vector from;
00066 if ( !current_view.features_in_region( from, from_set ) ) {
00067 DebugMacro( 1, "Cannot get features in current region!!!" << vcl_endl );
00068 return matches_sptr;
00069 }
00070
00071
00072 feat_vector matching_features;
00073 matching_features.reserve( 10 );
00074
00075 matches_sptr->reserve( from.size() );
00076
00077
00078 vnl_vector<double> prev_mapped;
00079 int reuse_match_count = 0;
00080 for ( feat_iter fitr = from.begin(); fitr != from.end(); ++fitr )
00081 {
00082 rgrl_feature_sptr mapped = (*fitr)->transform( current_xform );
00083 if ( !validate( mapped, current_view.to_image_roi() ) )
00084 continue;
00085
00086 matching_features.clear();
00087
00088 if ( allow_reuse_match )
00089 {
00090 prev_xform_->map_location( (*fitr)->location(), prev_mapped );
00091
00092
00093 vcl_map< rgrl_feature_sptr, from_feature_iterator >::const_iterator map_itr;
00094 if ( vnl_vector_ssd( prev_mapped, mapped->location() ) < sqr_thres_for_reuse_match_ &&
00095 (map_itr=feature_sptr_iterator_map.find( *fitr )) != feature_sptr_iterator_map.end() )
00096 {
00097
00098 const from_feature_iterator& prev_from_iter = map_itr->second;
00099 for ( from_feature_iterator::to_iterator titr=prev_from_iter.begin(); titr!=prev_from_iter.end(); ++titr )
00100 matching_features.push_back( titr.to_feature() );
00101
00102
00103 ++reuse_match_count;
00104 }
00105 else
00106 to_set.k_nearest_features( matching_features, mapped, k_ );
00107 }
00108 else
00109 to_set.k_nearest_features( matching_features, mapped, k_ );
00110
00111 if ( debug_flag()>=4 )
00112 {
00113 vcl_cout << " From feature: ";
00114 (*fitr)->write( vcl_cout );
00115 vcl_cout << vcl_endl;
00116 for ( unsigned i=0; i<matching_features.size(); ++i ) {
00117 vcl_cout << " ###### " << i << " ###### " << vcl_endl;
00118 matching_features[i]->write(vcl_cout);
00119 }
00120 }
00121
00122
00123
00124 double max_weight = -1;
00125 double min_eucl_dist = 1e10;
00126 rgrl_feature_sptr max_feature;
00127 for ( feat_iter i = matching_features.begin(); i != matching_features.end(); ++i )
00128 {
00129 double eucl_dist = vnl_vector_ssd( (*i)->location(), mapped->location() );
00130 if ( thres_ > 0 && eucl_dist > thres_ )
00131 continue;
00132
00133 double wgt = (*i)->absolute_signature_weight( mapped );
00134
00135 if ( wgt > max_weight )
00136 {
00137
00138 max_weight = wgt;
00139 min_eucl_dist = eucl_dist;
00140 max_feature = *i;
00141 }
00142 else if ( vcl_abs( wgt-max_weight) < 1e-12 && eucl_dist < min_eucl_dist )
00143 {
00144
00145
00146
00147 max_weight = wgt;
00148 min_eucl_dist = eucl_dist;
00149 max_feature = *i;
00150 }
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 if ( max_feature )
00167 {
00168 matches_sptr->add_feature_and_match( *fitr, mapped, max_feature, max_weight );
00169 DebugMacro( 4, " ====== Final Choice ======\n" );
00170 if ( debug_flag() >=4 ) {
00171 max_feature->write(vcl_cout);
00172 vcl_cout << vcl_endl;
00173 }
00174 }
00175 }
00176
00177 DebugMacro( 1, "There are " << reuse_match_count << " reuse of previous matches out of " << from.size() << vcl_endl );
00178
00179
00180 prev_xform_ = current_view.xform_estimate();
00181
00182 return matches_sptr;
00183 }
00184
00185
00186
00187 void
00188 rgrl_matcher_k_nearest_pick_one::
00189 add_one_flipped_match( rgrl_match_set_sptr& inv_set,
00190 rgrl_view const& current_view,
00191 nodes_vec_iterator const& begin_iter,
00192 nodes_vec_iterator const& end_iter )
00193 {
00194 const unsigned int size = unsigned( end_iter - begin_iter );
00195 rgrl_transformation_sptr const& inverse_xform = current_view.inverse_xform_estimate();
00196
00197
00198 rgrl_feature_sptr from = begin_iter->to_;
00199 rgrl_feature_sptr mapped = from->transform( *inverse_xform );
00200
00201
00202 if ( !validate( mapped, current_view.from_image_roi() ) )
00203 return;
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 vcl_vector< internal_dist_node > dist_nodes;
00214 dist_nodes.reserve( size );
00215 for ( nodes_vec_iterator itr = begin_iter; itr!=end_iter; ++itr )
00216 {
00217 internal_dist_node tmp_node;
00218
00219
00220
00221
00222 tmp_node.geo_err_ = vnl_vector_ssd( itr->from_->location(), mapped->location() );
00223 tmp_node.itr_ = itr;
00224
00225
00226 dist_nodes.push_back( tmp_node );
00227 }
00228
00229
00230
00231 if ( size > k_ )
00232 vcl_nth_element( dist_nodes.begin(), dist_nodes.begin()+k_, dist_nodes.end() );
00233
00234
00235
00236 double max_weight = -1.0;
00237 double min_eucl_dist = 1e10;
00238 rgrl_feature_sptr max_feature;
00239 for ( unsigned i=0; i<k_ && i<size; ++i )
00240 {
00241 double eucl_dist = dist_nodes[i].geo_err_;
00242 if ( thres_ > 0 && eucl_dist > thres_ )
00243 continue;
00244
00245
00246
00247 rgrl_feature_sptr const& one_fea = dist_nodes[i].itr_->from_;
00248 double wgt = one_fea->absolute_signature_weight( mapped );
00249
00250 if ( wgt > max_weight )
00251 {
00252
00253 max_weight = wgt;
00254 min_eucl_dist = eucl_dist;
00255 max_feature = one_fea;
00256 }
00257 else if ( vcl_abs( wgt-max_weight) < 1e-12 && eucl_dist < min_eucl_dist )
00258 {
00259
00260
00261
00262 max_weight = wgt;
00263 min_eucl_dist = eucl_dist;
00264 max_feature = one_fea;
00265 }
00266 }
00267
00268
00269 if ( max_feature )
00270 inv_set->add_feature_and_match( from, mapped, max_feature, max_weight );
00271 }
00272
00273 inline
00274 bool
00275 rgrl_matcher_k_nearest_pick_one::
00276 validate( rgrl_feature_sptr const& mapped, rgrl_mask_sptr const& roi_sptr ) const
00277 {
00278
00279 if ( !roi_sptr->inside( mapped->location() ) )
00280 return false;
00281
00282
00283
00284
00285
00286
00287
00288
00289 const double scale = mapped->scale();
00290 if ( scale!=0 && min_mapped_scale_>0 && scale<min_mapped_scale_ ) {
00291 return false;
00292 }
00293
00294
00295 return true;
00296 }