contrib/rpl/rgrl/rgrl_feature_landmark.cxx
Go to the documentation of this file.
00001 #include "rgrl_feature_landmark.h"
00002 //:
00003 // \file
00004 // \author Amitha Perera
00005 // \date Feb 2002
00006 
00007 #include <rgrl/rgrl_transformation.h>
00008 #include <rgrl/rgrl_cast.h>
00009 #include <rgrl/rgrl_util.h>
00010 
00011 #include <vnl/vnl_math.h>
00012 #include <vcl_cassert.h>
00013 
00014 typedef vcl_vector< vnl_vector<double> > vec_vec_type;
00015 
00016 rgrl_feature_landmark::
00017 rgrl_feature_landmark( vnl_vector<double> const& loc,
00018                        vcl_vector< vnl_vector<double> > const& outgoing_directions)
00019   : rgrl_feature( loc ),
00020     error_proj_( loc.size(), loc.size(), vnl_matrix_identity ),
00021     outgoing_directions_( outgoing_directions )
00022 {
00023   assert(outgoing_directions_.size() > 0);
00024 }
00025 
00026 
00027 rgrl_feature_landmark::
00028 rgrl_feature_landmark( rgrl_feature_landmark const& other )
00029   : rgrl_feature(other),
00030     error_proj_( other.error_proj_ ),
00031     outgoing_directions_( other.outgoing_directions_ )
00032 {
00033 }
00034 
00035 rgrl_feature_landmark::
00036 rgrl_feature_landmark( )
00037 {
00038 }
00039 
00040 vnl_matrix<double> const&
00041 rgrl_feature_landmark::
00042 error_projector() const
00043 {
00044   return error_proj_;
00045 }
00046 
00047 vnl_matrix<double> const&
00048 rgrl_feature_landmark::
00049 error_projector_sqrt() const
00050 {
00051   // they are the same
00052   return error_proj_;
00053 }
00054 
00055 
00056 unsigned int
00057 rgrl_feature_landmark::
00058 num_constraints() const
00059 {
00060   return location_.size();
00061 }
00062 
00063 rgrl_feature_sptr
00064 rgrl_feature_landmark::
00065 transform( rgrl_transformation const& xform ) const
00066 {
00067   rgrl_feature_landmark* result = new rgrl_feature_landmark( *this );
00068 
00069   // Transform the location
00070   //
00071   xform.map_location( this->location_, result->location_ );
00072 
00073   // Transform each of the direction vectors
00074   //
00075   vec_vec_type::const_iterator fitr = this->outgoing_directions_.begin();
00076   vec_vec_type::const_iterator fend = this->outgoing_directions_.end();
00077   vec_vec_type::iterator titr = result->outgoing_directions_.begin();
00078   for ( ; fitr != fend; ++fitr, ++titr ) {
00079     xform.map_direction( this->location_, *fitr, *titr );
00080   }
00081 
00082   return result;
00083 }
00084 
00085 double
00086 rgrl_feature_landmark::
00087 absolute_signature_weight( rgrl_feature_sptr other ) const
00088 {
00089   if ( !other->is_type( rgrl_feature_landmark::type_id() ) )
00090     return 1;
00091 
00092   rgrl_feature_landmark* other_ptr = rgrl_cast<rgrl_feature_landmark *>(other);
00093   const vcl_vector<vnl_vector<double> >& sig_P = this->outgoing_directions_;
00094   const vcl_vector<vnl_vector<double> >& sig_Q = other_ptr->outgoing_directions_;
00095 
00096   int ones = vnl_math_min((int)sig_P.size(), (int)sig_Q.size());
00097   double max;
00098   if (sig_P.size() < sig_Q.size()) {
00099     vbl_array_2d<bool> invalid(sig_P.size(), sig_Q.size(), false);
00100     max = max_similarity(sig_P, sig_Q, ones, invalid);
00101   }
00102   else {
00103     vbl_array_2d<bool> invalid(sig_Q.size(), sig_P.size(), false);
00104     max = max_similarity(sig_Q, sig_P, ones, invalid);
00105   }
00106 
00107   return vcl_pow( 0.5*max/ones, 100 );
00108 }
00109 
00110 
00111 // A resursive function to calculate the max similarity of two landmarks
00112 //
00113 double
00114 rgrl_feature_landmark::
00115 max_similarity(const vcl_vector<vnl_vector<double> >& u,
00116                const vcl_vector<vnl_vector<double> >& v,
00117                int count,
00118                const vbl_array_2d<bool>& invalid) const
00119 {
00120   if (count == 0) return 0.0;
00121 
00122   double max = 0.0;
00123   for (unsigned int j = 0; j < v.size(); j++) {
00124     if (!invalid(count-1,j)) {
00125       vbl_array_2d<bool> invalid2(invalid);
00126       for ( unsigned k = 0; k < u.size(); k++)
00127         invalid2.put(k,j,true);
00128       for ( unsigned k = 0; k < v.size(); k++)
00129         invalid2.put(count-1,k,true);
00130       double sum  = dot_product(u[count-1],v[j]) + 1 +
00131         max_similarity(u, v, count-1, invalid2);
00132       if (max < sum) max = sum;
00133     }
00134   }
00135   return max ;
00136 }
00137 
00138 //: write out feature
00139 void
00140 rgrl_feature_landmark::
00141 write( vcl_ostream& os ) const
00142 {
00143   // tag
00144   os << "LANDMARK" << vcl_endl;
00145 
00146   // dim
00147   os << location_.size() << vcl_endl;
00148 
00149   // atributes
00150   os << location_ << '\n'
00151      << error_proj_ << '\n'
00152      << outgoing_directions_.size() << '\n';
00153   for ( unsigned i=0; i<outgoing_directions_.size(); ++i )
00154     os << outgoing_directions_[i] << '\n';
00155   os << vcl_endl;
00156 }
00157 
00158 //: read in feature
00159 bool
00160 rgrl_feature_landmark::
00161 read( vcl_istream& is, bool skip_tag )
00162 {
00163   if ( !skip_tag )
00164   {
00165     // skip empty lines
00166     rgrl_util_skip_empty_lines( is );
00167 
00168     vcl_string str;
00169     vcl_getline( is, str );
00170 
00171     // The token should appear at the beginning of line
00172     if ( str.find( "LANDMARK" ) != 0 ) {
00173       WarningMacro( "The tag is not LANDMARK. reading is aborted.\n" );
00174       return false;
00175     }
00176   }
00177 
00178   // get dim
00179   int dim=-1;
00180   is >> dim;
00181   if ( !is || dim<=0 )
00182     return false;    // cannot get dimension
00183 
00184   // get location
00185   location_.set_size( dim );
00186   is >> location_;
00187   if ( !is )
00188     return false;   // cannot read location
00189 
00190   // get error projector
00191   error_proj_.set_size( dim, dim );
00192   is >> error_proj_;
00193   if ( !is )
00194     return false;
00195 
00196   // get outgoing directions
00197   int num=-1;
00198   is >> num;
00199   if ( !is || num<=0 )
00200     return false;
00201 
00202   outgoing_directions_.reserve( num );
00203   vnl_vector<double> one( dim );
00204   for (int i=0; i<num; ++i) {
00205     is >> one;
00206     if ( !is )
00207       return false;
00208     outgoing_directions_.push_back( one );
00209   }
00210 
00211   return true;
00212 }
00213 
00214 rgrl_feature_sptr
00215 rgrl_feature_landmark::
00216 clone() const
00217 {
00218   return new rgrl_feature_landmark(*this);
00219 }