00001
00002
00003
00004
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& )
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
00039
00040 assert(from_set.type() == rgrl_feature_trace_pt::type_id()
00041 && to_set.type() == rgrl_feature_trace_pt::type_id());
00042
00043
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 );
00055
00056
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
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
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
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 {
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