Go to the documentation of this file.00001
00002
00003 #include "rgrl_feature_face_pt.h"
00004 #include <rgrl/rgrl_transformation.h>
00005 #include <vnl/algo/vnl_svd.h>
00006 #include <vnl/vnl_math.h>
00007
00008 #include <vcl_cassert.h>
00009 #include <rgrl/rgrl_util.h>
00010 #include <rgrl/rgrl_cast.h>
00011
00012
00013 rgrl_feature_face_pt ::
00014 rgrl_feature_face_pt( vnl_vector< double > const& location,
00015 vnl_vector< double > const& normal )
00016 : rgrl_feature( location ), normal_( normal ),
00017 subspace_cached_( false )
00018 {
00019 normal_.normalize();
00020 }
00021
00022
00023 rgrl_feature_face_pt ::
00024 rgrl_feature_face_pt()
00025 : subspace_cached_( false )
00026 {
00027 }
00028
00029 vnl_matrix<double> const&
00030 rgrl_feature_face_pt ::
00031 error_projector() const
00032 {
00033 if(scale_ == 0){
00034 WarningMacro( "The scale is zero." );
00035 }
00036 if( !err_proj_.size() ) {
00037 err_proj_ = outer_product( normal_, normal_ ) ;
00038 err_proj_ /= vnl_math_sqr( scale_ );
00039 }
00040
00041 return err_proj_;
00042 }
00043
00044 vnl_matrix<double> const&
00045 rgrl_feature_face_pt ::
00046 error_projector_sqrt() const
00047 {
00048 if(scale_ == 0){
00049 WarningMacro( "The scale is zero." );
00050 }
00051 if( !err_proj_sqrt_.size() ) {
00052 err_proj_sqrt_ = outer_product( normal_, normal_ ) ;
00053 err_proj_sqrt_ /= scale_;
00054 }
00055
00056 return err_proj_sqrt_;
00057 }
00058
00059 unsigned int
00060 rgrl_feature_face_pt::
00061 num_constraints() const
00062 {
00063 return 1;
00064 }
00065
00066 vnl_vector<double> const&
00067 rgrl_feature_face_pt :: normal() const
00068 {
00069 return normal_;
00070 }
00071
00072 vnl_matrix<double> const&
00073 rgrl_feature_face_pt ::
00074 tangent_subspace()
00075 {
00076 if ( subspace_cached_ )
00077 return tangent_subspace_;
00078
00079 vnl_matrix<double> one_row( 1, this -> normal_.size() );
00080 one_row.set_row( 0, this -> normal_ );
00081 vnl_svd<double> normal_svd( one_row );
00082 tangent_subspace_ = normal_svd.nullspace();
00083 assert( tangent_subspace_ . columns() == this -> normal_ . size() - 1 );
00084 subspace_cached_ = true;
00085 return tangent_subspace_;
00086 }
00087
00088 rgrl_feature_sptr
00089 rgrl_feature_face_pt ::
00090 transform( rgrl_transformation const& xform ) const
00091 {
00092 rgrl_feature_face_pt* face_ptr = new rgrl_feature_face_pt();
00093
00094
00095 rgrl_feature_sptr result_sptr = face_ptr;
00096
00097 xform.map_location( this->location_, face_ptr->location_ );
00098 xform.map_normal( this->location_, this->normal_, face_ptr->normal_ );
00099
00100
00101
00102
00103 #if 0
00104
00105 if ( this->scale_ > 0.0 )
00106 face_ptr->scale_ = this->transform_scale( xform );
00107 #else
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 vnl_vector<double> loc(normal_), xformed_loc(face_ptr->location_.size());
00121 loc *= scale_;
00122 loc += location_;
00123
00124
00125 xform.map_location( loc, xformed_loc );
00126
00127
00128 xformed_loc -= face_ptr->location_;
00129
00130 face_ptr->scale_ = xformed_loc.magnitude();
00131 #endif
00132
00133 return result_sptr;
00134 }
00135
00136 double
00137 rgrl_feature_face_pt::
00138 transform_scale( rgrl_transformation const& xform ) const
00139 {
00140 assert( !"should not use this function. The reason is above in the transform() function." );
00141
00142
00143 vnl_vector<double> const& scaling = xform.scaling_factors();
00144 const unsigned dim = this->location_.size();
00145 double scale = 0.0;
00146
00147 if ( this->scale_ > 0.0 && scaling.size() == dim ) {
00148
00149
00150
00151
00152 scale = 0.0;
00153 for ( unsigned i=0; i<normal_.size(); ++i )
00154 scale += vcl_abs(normal_[i]) * scaling[i];
00155 scale *= this->scale_;
00156
00157 } else if ( this-> scale_ > 0.0 ) {
00158 WarningMacro( "This feature has non-zero scale value, but transformation has no scaling factors."
00159 << "The scale of transformed features is NOT set." );
00160 }
00161
00162 return scale;
00163 }
00164
00165
00166
00167 double
00168 rgrl_feature_face_pt ::
00169 absolute_signature_weight( rgrl_feature_sptr other ) const
00170 {
00171
00172 if ( !other ) return 0.0;
00173
00174 rgrl_feature_face_pt* face_ptr = rgrl_cast<rgrl_feature_face_pt*>(other);
00175 assert( face_ptr );
00176 double dir_wgt = vcl_abs( dot_product( this->normal_, face_ptr->normal_ ) );
00177
00178 double scale_wgt = 1;
00179 if ( this->scale_ && face_ptr->scale_ ) {
00180 if ( this->scale_ >= face_ptr->scale_ )
00181 scale_wgt = face_ptr->scale_ / this->scale_;
00182 else
00183 scale_wgt = this->scale_ / face_ptr->scale_;
00184
00185
00186 }
00187
00188 return dir_wgt* vcl_sqrt(scale_wgt);
00189 }
00190
00191
00192 vnl_vector<double>
00193 rgrl_feature_face_pt::
00194 signature_error_vector( rgrl_feature const& other ) const
00195 {
00196 if( !other.is_type( rgrl_feature_face_pt::type_id() ) )
00197 return vnl_vector<double>();
00198
00199
00200 rgrl_feature_face_pt const& other_face_pt = static_cast<rgrl_feature_face_pt const&>(other);
00201
00202
00203 const double dot = dot_product( this->normal_, other_face_pt.normal_ );
00204 const double half_pi = vnl_math::pi / 2.0;
00205 double ang = vcl_acos( dot );
00206
00207
00208 if( ang > half_pi ) ang -= vnl_math::pi;
00209
00210 vnl_vector<double> error_vec(1, ang);
00211 return error_vec;
00212
00213 }
00214
00215
00216 unsigned
00217 rgrl_feature_face_pt::
00218 signature_error_dimension( const vcl_type_info& other_feature_type ) const
00219 {
00220 if( other_feature_type == rgrl_feature_face_pt::type_id() )
00221 return 1;
00222 else
00223 return 0;
00224 }
00225
00226
00227 void
00228 rgrl_feature_face_pt::
00229 write( vcl_ostream& os ) const
00230 {
00231
00232 os << "FACE\n"
00233
00234 << location_.size() << '\n'
00235
00236 << location_ << " " << scale_ << '\n'
00237 << normal_ << vcl_endl;
00238 }
00239
00240
00241 bool
00242 rgrl_feature_face_pt::
00243 read( vcl_istream& is, bool skip_tag )
00244 {
00245 if ( !skip_tag ) {
00246
00247
00248 rgrl_util_skip_empty_lines( is );
00249
00250 vcl_string str;
00251 vcl_getline( is, str );
00252
00253
00254 if ( str.find( "FACE" ) != 0 ) {
00255 WarningMacro( "The tag is not FACE. reading is aborted.\n" );
00256 return false;
00257 }
00258 }
00259
00260
00261 int dim=-1;
00262 is >> dim;
00263
00264 if ( !is || dim<=0 )
00265 return false;
00266
00267
00268 location_.set_size( dim );
00269 is >> location_;
00270 if ( !is )
00271 return false;
00272
00273
00274 is >> scale_;
00275 if ( !is )
00276 return false;
00277
00278
00279 normal_.set_size( dim );
00280 is >> normal_;
00281 if ( !is )
00282 return false;
00283
00284
00285 subspace_cached_ = false;
00286
00287 return true;
00288 }
00289
00290 rgrl_feature_sptr
00291 rgrl_feature_face_pt::
00292 clone() const
00293 {
00294 return new rgrl_feature_face_pt(*this);
00295 }