contrib/rpl/rgrl/rgrl_initializer_inv_indexing.cxx
Go to the documentation of this file.
00001 #include "rgrl_initializer_inv_indexing.h"
00002 
00003 #include <vcl_vector.h>
00004 #include <vcl_algorithm.h>
00005 #include <vcl_cassert.h>
00006 
00007 #include <rsdl/rsdl_kd_tree.h>
00008 
00009 #include "rgrl_view.h"
00010 #include "rgrl_util.h"
00011 #include "rgrl_invariant.h"
00012 #include "rgrl_invariant_match.h"
00013 #include "rgrl_est_translation.h"
00014 
00015 rgrl_initializer_inv_indexing::
00016 rgrl_initializer_inv_indexing( rgrl_view_sptr prior_view,
00017                                bool should_estimate_global_region,
00018                                int max_num_matches_tried )
00019   : view_ (prior_view),
00020     should_estimate_global_region_( should_estimate_global_region ),
00021     current_moving_image_ind_(0),
00022     num_matches_tried_( 0 ),
00023     max_num_matches_tried_( max_num_matches_tried )
00024 {
00025 }
00026 
00027 rgrl_initializer_inv_indexing::
00028 rgrl_initializer_inv_indexing( rgrl_mask_sptr const&     from_image_roi,
00029                                rgrl_mask_sptr const&     to_image_roi,
00030                                rgrl_estimator_sptr xform_estimator,
00031                                unsigned             initial_resolution,
00032                                bool should_estimate_global_region,
00033                                int max_num_matches_tried )
00034   : should_estimate_global_region_( should_estimate_global_region ),
00035     current_moving_image_ind_(0),
00036     num_matches_tried_( 0 ),
00037     max_num_matches_tried_( max_num_matches_tried )
00038 {
00039   // If xform_estimator is not set, assign the simplest estimator possible.
00040   if ( !xform_estimator ) {
00041     unsigned dim = from_image_roi->x0().size();
00042     xform_estimator = new rgrl_est_translation(dim);
00043   }
00044 
00045   rgrl_mask_box global_region( from_image_roi->bounding_box() );
00046   view_ = new rgrl_view( from_image_roi, to_image_roi,
00047                          global_region, global_region,
00048                          xform_estimator, 0,
00049                          initial_resolution );
00050 }
00051 
00052 void
00053 rgrl_initializer_inv_indexing::
00054 add_data( vcl_vector<rgrl_invariant_sptr> const& fixed_set,
00055           vcl_vector<rgrl_invariant_sptr> const& moving_set,
00056           double nn_radius,
00057           unsigned int k_nn )
00058 {
00059   vcl_vector<vcl_vector<rgrl_invariant_sptr> > moving_sets;
00060   moving_sets.push_back( moving_set );
00061   add_multiple_data( fixed_set, moving_sets, nn_radius , k_nn );
00062 }
00063 
00064 void
00065 rgrl_initializer_inv_indexing::
00066 add_multiple_data( vcl_vector<rgrl_invariant_sptr> const& fixed_set,
00067                    vcl_vector<vcl_vector<rgrl_invariant_sptr> > const& moving_sets,
00068                    double nn_radius,
00069                    unsigned int k_nn )
00070 {
00071   unsigned int num_moving_sets = moving_sets.size();
00072   assert (fixed_set.size() > 0);
00073 
00074   // allocate space for matches
00075   if ( matches_.empty() ) matches_.resize( num_moving_sets );
00076   else assert ( matches_.size() == num_moving_sets );
00077 
00078   // Obtain the number of cartesian, nc, and number of angular, na,
00079   // from the first invariant feature
00080   unsigned int nc = fixed_set[0]->cartesian_invariants().size();
00081   unsigned int na = fixed_set[0]->angular_invariants().size();
00082 
00083   // Construct a kd-tree for the set of search points from the fixed_set
00084   vcl_vector<rsdl_point> search_pts(fixed_set.size());
00085   for (unsigned int pt=0; pt<fixed_set.size(); ++pt) {
00086     // Set number of expected cartesian and angular values
00087     search_pts[pt].resize( nc, na );
00088     search_pts[pt].set_cartesian(fixed_set[pt]->cartesian_invariants());
00089     search_pts[pt].set_angular(fixed_set[pt]->angular_invariants());
00090   }
00091   rsdl_kd_tree kd_tree( search_pts );
00092 
00093   // Iterate through the features from each moving set
00094   for (unsigned int m_ind = 0; m_ind<num_moving_sets; ++m_ind)
00095   {
00096     // Iterate through all constellations/points in the current "from" image
00097     for (unsigned int pt = 0; pt<moving_sets[m_ind].size(); pt++)
00098     {
00099       // Create a query point from the invariants of the current constellation
00100       rsdl_point query_pt( nc, na );
00101       query_pt.set_cartesian(moving_sets[m_ind][pt]->cartesian_invariants());
00102       query_pt.set_angular(moving_sets[m_ind][pt]->angular_invariants());
00103 
00104       // Find all points (and their indices) within nn_radius of the query_pt
00105       vcl_vector<rsdl_point> near_neighbor_pts;
00106       vcl_vector<int> near_neighbor_indices;
00107       if ( nn_radius > 0.0 ) {
00108         kd_tree.points_in_radius( query_pt, nn_radius, near_neighbor_pts,
00109                                   near_neighbor_indices );
00110       }
00111       // If no points were found in nn_radius, find the nearest point
00112       if (near_neighbor_indices.empty() ) {
00113         kd_tree.n_nearest( query_pt, k_nn, near_neighbor_pts, near_neighbor_indices );
00114       }
00115 
00116       // Create matches from the nearest neighbors and push them onto
00117       // the current vector
00118       for (unsigned int nn_ind = 0; nn_ind<near_neighbor_indices.size(); ++nn_ind) {
00119         matches_[m_ind].push_back( new rgrl_invariant_match(moving_sets[m_ind][pt], fixed_set[near_neighbor_indices[nn_ind]]) );
00120       }
00121     }
00122     vcl_sort(matches_[m_ind].begin(), matches_[m_ind].end(), dist_greater);
00123   }
00124 }
00125 
00126 void
00127 rgrl_initializer_inv_indexing::
00128 set_current_moving_image( unsigned int moving_image_index)
00129 {
00130   current_moving_image_ind_ = moving_image_index;
00131   num_matches_tried_ = 0;
00132 }
00133 
00134 const vcl_vector<rgrl_invariant_match_sptr>&
00135 rgrl_initializer_inv_indexing::
00136 matches_for_moving_image( unsigned int moving_image_index)
00137 {
00138   return matches_[moving_image_index];
00139 }
00140 
00141 bool
00142 rgrl_initializer_inv_indexing::
00143 next_initial( rgrl_view_sptr           & view,
00144               rgrl_scale_sptr          & prior_scale)
00145 {
00146   if ( max_num_matches_tried_ > 0 &&
00147        num_matches_tried_ == max_num_matches_tried_ )
00148     return false;
00149 
00150   rgrl_invariant_match_sptr best_match;
00151   if (matches_[current_moving_image_ind_].empty())
00152     return false;
00153 
00154   bool found_best_match;
00155   // Remove the best (last) match from the vector
00156   do {
00157     best_match = matches_[current_moving_image_ind_].back();
00158     matches_[current_moving_image_ind_].pop_back();
00159     ++num_matches_tried_;
00160     found_best_match = best_match->estimate();
00161   } while ( !found_best_match && !matches_[current_moving_image_ind_].empty());
00162 
00163   if ( !found_best_match ) return false;
00164 
00165   // Determine the global region
00166   //
00167   rgrl_mask_box global_region ( view_->from_image_roi()->bounding_box() );
00168   if ( should_estimate_global_region_ )
00169     global_region =
00170       rgrl_util_estimate_global_region(view_->from_image_roi(),
00171                                        view_->to_image_roi(),
00172                                        view_->from_image_roi()->bounding_box(),
00173                                        *best_match->transform());
00174   // Determine the initial region
00175   //
00176   rgrl_mask_box initial_region( view_->from_image_roi()->bounding_box() );
00177   if ( best_match->has_initial_region() )
00178     initial_region = best_match->initial_region();
00179 
00180   view = new rgrl_view( view_->from_image_roi(),
00181                         view_->to_image_roi(),
00182                         initial_region,
00183                         global_region,
00184                         view_->xform_estimator(),
00185                         best_match->transform(),
00186                         view_->resolution() );
00187   prior_scale = rgrl_initializer::enforce_prior_scale( best_match->scale() );
00188 
00189   return true;
00190 }
00191 
00192 bool
00193 rgrl_initializer_inv_indexing::
00194 next_initial( rgrl_invariant_match_sptr& best_match )
00195 {
00196   if ( max_num_matches_tried_ > 0 &&
00197        num_matches_tried_ == max_num_matches_tried_ )
00198     return false;
00199 
00200   if (matches_[current_moving_image_ind_].empty())
00201     return false;
00202 
00203   bool found_best_match;
00204   // Remove the best (last) match from the vector
00205   do {
00206     best_match = matches_[current_moving_image_ind_].back();
00207     matches_[current_moving_image_ind_].pop_back();
00208     ++num_matches_tried_;
00209     found_best_match = best_match->estimate();
00210   }
00211   while ( !found_best_match && !matches_[current_moving_image_ind_].empty());
00212 
00213   return found_best_match;
00214 }
00215 
00216 int
00217 rgrl_initializer_inv_indexing::
00218 size() const
00219 {
00220   return int(matches_[current_moving_image_ind_].size());
00221 }