Go to the documentation of this file.00001 #include "rgrl_matcher_k_nearest.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 bool
00017 rgrl_matcher_k_nearest::internal_dist_node::
00018 operator<( internal_dist_node const& rhs ) const
00019 {
00020 return this->geo_err_ < rhs.geo_err_;
00021 }
00022
00023 rgrl_matcher_k_nearest::
00024 rgrl_matcher_k_nearest( unsigned int k )
00025 : k_( k ),
00026 thres_( -1.0 )
00027 {
00028 }
00029
00030
00031 rgrl_matcher_k_nearest::
00032 rgrl_matcher_k_nearest( unsigned int k, double dist_thres )
00033 : k_( k ),
00034 thres_( dist_thres )
00035 {
00036 if ( thres_ > 0.0 ) thres_ = thres_*thres_;
00037 }
00038
00039
00040 rgrl_match_set_sptr
00041 rgrl_matcher_k_nearest::
00042 compute_matches( rgrl_feature_set const& from_set,
00043 rgrl_feature_set const& to_set,
00044 rgrl_view const& current_view,
00045 rgrl_transformation const& current_xform,
00046 rgrl_scale const& ,
00047 rgrl_match_set_sptr const& )
00048 {
00049 typedef rgrl_view::feature_vector feat_vector;
00050 typedef feat_vector::const_iterator feat_iter;
00051
00052 rgrl_match_set_sptr matches_sptr
00053 = new rgrl_match_set( from_set.type(), to_set.type(), from_set.label(), to_set.label() );
00054
00055
00056 feat_vector from;
00057 if( !current_view.features_in_region( from, from_set ) ) {
00058 DebugMacro( 1, "Cannot get features in current region!!!" << vcl_endl );
00059 return matches_sptr;
00060 }
00061
00062
00063 feat_vector matching_features, pruned_set;
00064 matching_features.reserve( 10 );
00065 pruned_set.reserve( 10 );
00066
00067 matches_sptr->reserve( from.size() );
00068
00069
00070 for ( feat_iter fitr = from.begin(); fitr != from.end(); ++fitr )
00071 {
00072 rgrl_feature_sptr mapped = (*fitr)->transform( current_xform );
00073 if ( !validate( mapped, current_view.to_image_roi() ) )
00074 continue;
00075
00076 matching_features.clear();
00077 to_set.k_nearest_features( matching_features, mapped, k_ );
00078
00079
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
00102
00103 void
00104 rgrl_matcher_k_nearest::
00105 add_one_flipped_match( rgrl_match_set_sptr& inv_set,
00106 rgrl_view const& current_view,
00107 nodes_vec_iterator const& begin_iter,
00108 nodes_vec_iterator const& end_iter )
00109 {
00110 const unsigned int size = unsigned( end_iter - begin_iter );
00111 rgrl_transformation_sptr const& inverse_xform = current_view.inverse_xform_estimate();
00112
00113
00114 rgrl_feature_sptr from = begin_iter->to_;
00115 rgrl_feature_sptr mapped = from->transform( *inverse_xform );
00116
00117 if ( !validate( mapped, current_view.from_image_roi() ) )
00118 return;
00119
00120
00121
00122
00123 vcl_vector< internal_dist_node > dist_nodes;
00124 dist_nodes.reserve( size );
00125 for ( nodes_vec_iterator itr = begin_iter; itr!=end_iter; ++itr )
00126 {
00127 internal_dist_node tmp_node;
00128
00129
00130
00131
00132 tmp_node.geo_err_ = vnl_vector_ssd( itr->from_->location(), mapped->location() );
00133 tmp_node.itr_ = itr;
00134
00135
00136 dist_nodes.push_back( tmp_node );
00137 }
00138
00139
00140 if ( size > k_ )
00141 vcl_nth_element( dist_nodes.begin(), dist_nodes.begin()+k_, dist_nodes.end() );
00142
00143
00144 vcl_vector< rgrl_feature_sptr > matching_tos;
00145 vcl_vector< double > sig_wgts;
00146 matching_tos.reserve( k_ );
00147 sig_wgts.reserve( k_ );
00148
00149 for ( unsigned i=0; i<k_ && i<size; ++i )
00150 {
00151 if ( thres_ > 0 && dist_nodes[i].geo_err_ > thres_ )
00152 continue;
00153
00154 nodes_vec_iterator const& current_node = dist_nodes[i].itr_;
00155 matching_tos.push_back( current_node->from_ );
00156
00157
00158
00159
00160 double wgt = current_node->from_->absolute_signature_weight( mapped );
00161 sig_wgts.push_back( wgt );
00162
00163 }
00164
00165
00166 if ( ! matching_tos.empty() )
00167 inv_set->add_feature_matches_and_weights( from, mapped, matching_tos, sig_wgts );
00168 }
00169
00170 bool
00171 rgrl_matcher_k_nearest::
00172 validate( rgrl_feature_sptr const& mapped, rgrl_mask_sptr const& roi_sptr ) const
00173 {
00174
00175 if ( !roi_sptr->inside( mapped->location() ) )
00176 return false;
00177
00178
00179
00180
00181
00182
00183
00184 #if 0
00185
00186 const double scale = mapped->scale();
00187 if ( scale!=0 && scale<0.4 ) {
00188 return false;
00189 }
00190 #endif // 0
00191
00192
00193 return true;
00194 }