contrib/rpl/rgrl/rgrl_matcher_k_nearest_boundary.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \author Charlene Tsai
00004 // \date   Sep 2003
00005 
00006 #include "rgrl_matcher_k_nearest_boundary.h"
00007 #include "rgrl_match_set.h"
00008 #include "rgrl_feature_set.h"
00009 #include "rgrl_feature_trace_pt.h"
00010 #include "rgrl_cast.h"
00011 #include <vcl_cassert.h>
00012 
00013 rgrl_matcher_k_nearest_boundary::
00014 rgrl_matcher_k_nearest_boundary( unsigned int k )
00015   : rgrl_matcher_k_nearest(k)
00016 {
00017 }
00018 
00019 rgrl_matcher_k_nearest_boundary::
00020 rgrl_matcher_k_nearest_boundary( unsigned int k, double dist_thres  )
00021   : rgrl_matcher_k_nearest(k, dist_thres)
00022 {
00023 }
00024 
00025 rgrl_match_set_sptr
00026 rgrl_matcher_k_nearest_boundary::
00027 compute_matches( rgrl_feature_set const&       from_set,
00028                  rgrl_feature_set const&       to_set,
00029                  rgrl_view const&              current_view,
00030                  rgrl_transformation const&    current_xform,
00031                  rgrl_scale const&             current_scale,
00032                  rgrl_match_set_sptr const&    /*old_matches*/ )
00033 {
00034   typedef rgrl_match_set::from_iterator FIter;
00035   typedef FIter::to_iterator TIter;
00036   typedef feature_vector::const_iterator fvec_Iter;
00037 
00038   //rgrl_matcher_k_nearest_boundary only works on RGRL_TRACE_PT
00039   //
00040   assert(from_set.type() == rgrl_feature_trace_pt::type_id()
00041          && to_set.type() == rgrl_feature_trace_pt::type_id());
00042 
00043   //1. get the center-point matches using the base class implementation
00044   //
00045   rgrl_match_set_sptr cp_matches =
00046     rgrl_matcher_k_nearest::compute_matches(from_set, to_set, current_view,
00047                                             current_xform, current_scale);
00048 
00049   rgrl_match_set_sptr bd_matches
00050     = new rgrl_match_set( from_set.type(), to_set.type(), from_set.label(), to_set.label() );
00051 
00052   if ( cp_matches->from_size() == 0 ) return bd_matches;
00053 
00054   assert( cp_matches->from_begin().from_feature()->location().size() == 2 ); //For now, only deal with 2D
00055 
00056   //2. For each center-point match, compute the boundary matches
00057   //
00058   for ( FIter fi = cp_matches->from_begin(); fi != cp_matches->from_end(); ++fi ) {
00059     rgrl_feature_trace_pt* from_feature =
00060       rgrl_cast<rgrl_feature_trace_pt *>(fi.from_feature());
00061     feature_vector from_bd_pts = from_feature->boundary_points(vnl_vector<double>());
00062 
00063     //transform the boundary points
00064     feature_vector mapped_bd_pts;
00065     for (fvec_Iter mi = from_bd_pts.begin(); mi != from_bd_pts.end(); ++mi) {
00066       mapped_bd_pts.push_back((*mi)->transform( current_xform ));
00067     }
00068 
00069     //assign the corresponding to_pt_boundary points to the from_boundary_points
00070     vcl_vector<feature_vector> to_bd_pt_set(from_bd_pts.size());
00071     for ( TIter ti = fi.begin(); ti != fi.end(); ++ti ) {
00072       rgrl_feature_trace_pt* to_feature =
00073         rgrl_cast<rgrl_feature_trace_pt *>(ti.to_feature());
00074       feature_vector to_bd_pts = to_feature->boundary_points(vnl_vector<double>());
00075       vbl_array_2d<bool> assignment = match_boundary_pts(mapped_bd_pts, to_bd_pts);
00076 
00077       typedef vbl_array_2d<bool>::size_type size_type;
00078       for (size_type i = 0; i<assignment.rows(); ++i)
00079         for (size_type j = 0; j<assignment.cols(); ++j){
00080           if (assignment(i,j)) to_bd_pt_set[i].push_back(to_bd_pts[j]);
00081         }
00082     }
00083 
00084     // Store the results into the bd_matches
00085     for (unsigned i = 0; i<from_bd_pts.size(); ++i) {
00086       bd_matches->add_feature_and_matches( from_bd_pts[i], mapped_bd_pts[i],
00087                                            to_bd_pt_set[i]);
00088     }
00089   }
00090 
00091   return bd_matches;
00092 }
00093 
00094 
00095 vbl_array_2d<bool>
00096 rgrl_matcher_k_nearest_boundary::
00097 match_boundary_pts(feature_vector const& from_pts,
00098                    feature_vector const& to_pts) const
00099 {
00100   assert(from_pts.size() == to_pts.size());
00101 
00102   vbl_array_2d<double> dist_errors( from_pts.size(), to_pts.size());
00103   typedef vbl_array_2d<double>::size_type size_type;
00104   for (size_type i = 0; i<dist_errors.rows(); ++i) {
00105     for (size_type j = 0; j<dist_errors.cols(); ++j) {
00106       dist_errors(i,j) = vnl_vector_ssd(from_pts[i]->location(),to_pts[j]->location());
00107     }
00108   }
00109 
00110   vbl_array_2d<bool> assignment(from_pts.size(), to_pts.size(), false);
00111 
00112   if ( from_pts.size() == 2 ) {
00113     if ( dist_errors(0,0) + dist_errors(1,1) >  dist_errors(0,1) + dist_errors(1,0) )
00114       assignment(0,1) = assignment(1,0) = true;
00115     else assignment(0,0) = assignment(1,1) = true;
00116   }
00117   else { //for more than 2 boundary points, using dynamic programming
00118     vbl_array_2d<bool> valid(from_pts.size(), to_pts.size(), true);
00119     double min_obj;
00120     vbl_array_2d<bool> assignment = match_boundary_pts_helper(dist_errors, valid, from_pts.size(), min_obj);
00121   }
00122 
00123   return assignment;
00124 }
00125 
00126 vbl_array_2d<bool>
00127 rgrl_matcher_k_nearest_boundary::
00128 match_boundary_pts_helper(vbl_array_2d<double> const& dist_error,
00129                           vbl_array_2d<bool> const& valid,
00130                           int count, double& obj_value) const
00131 {
00132   if (count == 0) {
00133     obj_value = 0.0;
00134     return vbl_array_2d<bool>(dist_error.rows(), dist_error.cols(), false);
00135   }
00136 
00137   vbl_array_2d<bool> best_assignment;
00138   double obj;
00139   bool min_obj_set = false;
00140 
00141   typedef vbl_array_2d<bool>::size_type size_type;
00142   for (size_type i = 0; i < valid.cols(); i++) {
00143     if (valid(count-1,i)) {
00144       vbl_array_2d<bool> valid2(valid);
00145       for ( size_type j = 0; j < valid.rows(); j++)
00146          valid2.put(j,i,false);
00147       for ( size_type j = 0; j < valid.cols(); j++)
00148          valid2.put(count-1,j,false);
00149       vbl_array_2d<bool> assignment =
00150         match_boundary_pts_helper(dist_error, valid2, count-1, obj);
00151       obj += dist_error(count-1,i);
00152       if (!min_obj_set || obj_value > obj) {
00153         min_obj_set = true;
00154         obj_value = obj;
00155         best_assignment =  assignment;
00156         best_assignment(count-1,i) = true;
00157       }
00158     }
00159   }
00160 
00161   return best_assignment;
00162 }
00163