Go to the documentation of this file.00001 #include "rgrl_feature_trace_pt.h"
00002
00003
00004
00005
00006
00007 #include "rgrl_transformation.h"
00008 #include "rgrl_util.h"
00009 #include <vnl/algo/vnl_svd.h>
00010
00011 #include <vcl_cassert.h>
00012
00013 #include <rgrl/rgrl_cast.h>
00014
00015 rgrl_feature_trace_pt ::
00016 rgrl_feature_trace_pt()
00017 : rgrl_feature(),
00018 subspace_cached_( false ),
00019 length_( 0 ), radius_( 0 )
00020 {
00021
00022 }
00023
00024 rgrl_feature_trace_pt::
00025 rgrl_feature_trace_pt( vnl_vector<double> const& loc,
00026 vnl_vector<double> const& tangent )
00027 : rgrl_feature( loc ),
00028 tangent_( tangent ),
00029 error_proj_( loc.size(), loc.size(), vnl_matrix_identity ),
00030 subspace_cached_(false),
00031 length_( 0 ), radius_( 0 )
00032 {
00033 tangent_.normalize();
00034 error_proj_ -= outer_product( tangent_, tangent_ );
00035 }
00036
00037 rgrl_feature_trace_pt::
00038 rgrl_feature_trace_pt( vnl_vector<double> const& loc,
00039 vnl_vector<double> const& tangent,
00040 double length,
00041 double radius )
00042 : rgrl_feature( loc ),
00043 tangent_( tangent ),
00044 error_proj_( loc.size(), loc.size(), vnl_matrix_identity ),
00045 subspace_cached_(false),
00046 length_( length ), radius_( radius )
00047 {
00048 tangent_.normalize();
00049 error_proj_ -= outer_product( tangent_, tangent_ );
00050 }
00051
00052
00053
00054 unsigned int
00055 rgrl_feature_trace_pt::
00056 num_constraints() const
00057 {
00058 return location_.size()-1;
00059 }
00060
00061 vnl_vector<double> const&
00062 rgrl_feature_trace_pt::
00063 tangent() const
00064 {
00065 return tangent_;
00066 }
00067
00068
00069 vnl_matrix<double> const&
00070 rgrl_feature_trace_pt::
00071 error_projector() const
00072 {
00073 return error_proj_;
00074 }
00075
00076 rgrl_feature_sptr
00077 rgrl_feature_trace_pt::
00078 transform( rgrl_transformation const& xform ) const
00079 {
00080 rgrl_feature_trace_pt* result = new rgrl_feature_trace_pt( );
00081
00082
00083 rgrl_feature_sptr result_sptr = result;
00084
00085
00086
00087 xform.map_location( this->location_, result->location_ );
00088 xform.map_tangent( this->location_, this->tangent_, result->tangent_ );
00089
00090
00091
00092 result->error_proj_.set_size( this->location_.size(), this->location_.size() );
00093 result->error_proj_.set_identity();
00094 result->error_proj_ -= outer_product( result->tangent_, result->tangent_ );
00095
00096
00097
00098
00099 result -> radius_ = this -> radius_;
00100 result -> length_ = this -> length_;
00101
00102 return result_sptr;
00103 }
00104
00105 vnl_matrix<double> const&
00106 rgrl_feature_trace_pt ::
00107 normal_subspace()
00108 {
00109 if ( subspace_cached_ )
00110 return normal_subspace_;
00111
00112
00113
00114
00115 vnl_matrix<double> one_row( 1, this -> tangent_.size() );
00116 one_row.set_row( 0, this -> tangent_ );
00117 vnl_svd<double> tangent_svd( one_row );
00118 normal_subspace_ = tangent_svd.nullspace();
00119 assert( normal_subspace_ . columns() == this -> tangent_ . size() - 1 );
00120 subspace_cached_ = true;
00121 return normal_subspace_;
00122 }
00123
00124 rgrl_feature_trace_pt::feature_vector
00125 rgrl_feature_trace_pt::
00126 boundary_points(vnl_vector<double> const& in_direction) const
00127 {
00128
00129
00130
00131 vnl_vector<double> normal(location_.size());
00132 if (location_.size() == 2) {
00133 normal[0] = -tangent_[1];
00134 normal[1] = tangent_[0];
00135 }
00136 else {
00137 normal = in_direction -
00138 dot_product(tangent_, in_direction)*tangent_;
00139 normal.normalize();
00140 }
00141
00142
00143
00144
00145
00146 feature_vector bdy_feature_points;
00147 rgrl_feature_sptr bd_pt = new rgrl_feature_trace_pt( location_+(normal*radius_), tangent_ );
00148 bdy_feature_points.push_back(bd_pt);
00149 bd_pt = new rgrl_feature_trace_pt( location_-(normal*radius_), tangent_ );
00150 bdy_feature_points.push_back(bd_pt);
00151
00152 return bdy_feature_points;
00153 }
00154
00155
00156 double
00157 rgrl_feature_trace_pt ::
00158 absolute_signature_weight( rgrl_feature_sptr other ) const
00159 {
00160
00161 if ( !other ) return 0.0;
00162
00163 rgrl_feature_trace_pt* trace_ptr = rgrl_cast<rgrl_feature_trace_pt*>(other);
00164 assert( trace_ptr );
00165 double dir_wgt = vcl_abs( dot_product( this->tangent_, trace_ptr->tangent_ ) );
00166
00167 double scale_wgt = 1;
00168 if ( this->scale_ && trace_ptr->scale_ ) {
00169 if ( this->scale_ >= trace_ptr->scale_ )
00170 scale_wgt = trace_ptr->scale_ / this->scale_;
00171 else
00172 scale_wgt = this->scale_ / trace_ptr->scale_;
00173
00174
00175 }
00176
00177 return dir_wgt* vcl_sqrt(scale_wgt);
00178 }
00179
00180
00181 void
00182 rgrl_feature_trace_pt::
00183 write( vcl_ostream& os ) const
00184 {
00185
00186 os << "TRACE" << vcl_endl;
00187
00188
00189 os << location_.size() << vcl_endl;
00190
00191
00192 os << location_ << " " << scale_ << "\n"
00193 << tangent_ << "\n"
00194 << error_proj_ << vcl_endl;
00195 }
00196
00197
00198 bool
00199 rgrl_feature_trace_pt::
00200 read( vcl_istream& is, bool skip_tag )
00201 {
00202 if( !skip_tag ) {
00203
00204
00205 rgrl_util_skip_empty_lines( is );
00206
00207 vcl_string str;
00208 vcl_getline( is, str );
00209
00210
00211 if ( str.find( "TRACE" ) != 0 ) {
00212 WarningMacro( "The tag is not TRACE. reading is aborted.\n" );
00213 return false;
00214 }
00215 }
00216
00217
00218 int dim=-1;
00219 is >> dim;
00220
00221 if( !is || dim<=0 )
00222 return false;
00223
00224
00225 location_.set_size( dim );
00226 is >> location_;
00227 if( !is )
00228 return false;
00229
00230
00231 is >> scale_;
00232 if( !is )
00233 return false;
00234
00235
00236 tangent_.set_size( dim );
00237 is >> tangent_;
00238 if( !is )
00239 return false;
00240
00241
00242 error_proj_.set_size( dim, dim );
00243 is >> error_proj_;
00244 if( !is )
00245 return false;
00246
00247
00248 subspace_cached_ = false;
00249
00250 return true;
00251 }
00252
00253 rgrl_feature_sptr
00254 rgrl_feature_trace_pt::
00255 clone() const
00256 {
00257 return new rgrl_feature_trace_pt(*this);
00258 }