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