00001 #ifndef rgrl_feature_h_ 00002 #define rgrl_feature_h_ 00003 //: 00004 // \file 00005 // \brief Base class for feature in generalized registration library 00006 // \author Chuck Stewart 00007 // \date 12 Nov 2002 00008 // \verbatim 00009 // Modifications 00010 // Nov 2008 J Becker: Added a clone function. 00011 // \endverbatim 00012 00013 #include <vcl_cassert.h> 00014 #include <vnl/vnl_vector.h> 00015 #include <vnl/vnl_matrix.h> 00016 00017 #include "rgrl_feature_sptr.h" 00018 #include "rgrl_feature_reader.h" 00019 #include "rgrl_object.h" 00020 #include <vcl_iosfwd.h> 00021 00022 class rgrl_transformation; 00023 00024 //: Represents a feature ("data point") used by the registration algorithms. 00025 // 00026 class rgrl_feature 00027 : public rgrl_object 00028 { 00029 public: 00030 00031 //: ctor 00032 rgrl_feature() 00033 : scale_( 1.0 ) 00034 { } 00035 00036 //: ctor 00037 rgrl_feature( vnl_vector<double> const& loc, double scale = 1.0 ) 00038 : location_( loc ), 00039 scale_( scale ) 00040 { 00041 assert(scale_ > 0); 00042 } 00043 00044 //: 00045 virtual ~rgrl_feature() {} 00046 00047 //: Apply a transformation to create a new feature. 00048 virtual 00049 rgrl_feature_sptr transform( rgrl_transformation const& xform ) const = 0; 00050 00051 //: Provide the geometric location. 00052 vnl_vector<double> const& location() const 00053 { return location_; } 00054 00055 //: set location 00056 void set_location( vnl_vector<double>const& loc ) 00057 { location_ = loc; } 00058 00059 unsigned dim() const 00060 { return location_.size(); } 00061 00062 //: Provide the scale level at which this feature is detected 00063 // If no associated scale, return 0 00064 double scale() const 00065 { return scale_; } 00066 00067 //: Set the scale level at which this feature is detected 00068 void set_scale( double scale ) 00069 { scale_ = scale; assert(scale_ > 0); } 00070 00071 //: read in feature 00072 virtual 00073 bool read( vcl_istream& is, bool skip_tag=false ) = 0; 00074 00075 //: write out feature 00076 virtual 00077 void write( vcl_ostream& os ) const = 0; 00078 00079 //: Projects the error to the normal space of the underlying surface. 00080 // 00081 // This matrix essentially describes the underlying surface from 00082 // which this feature arises. For a normal point, this would be the 00083 // identity matrix, implying that all dimensions of the error vector 00084 // are significant. For a point on a curve, this matrix could remove 00085 // this component of the error in the tangential direction, because 00086 // we are only interested in the error normal to the curve. 00087 // 00088 // Defaults to the identity matrix. 00089 // 00090 virtual 00091 vnl_matrix<double> const& error_projector() const = 0; 00092 00093 //: The square root of error projector is used to compute residual, which should not be squared. 00094 // The error projector itself is usually used in least-squares estimation. 00095 virtual 00096 vnl_matrix<double> const& error_projector_sqrt() const; 00097 00098 //: Number of constraints provided when another feature matches to it 00099 virtual 00100 unsigned int num_constraints() const = 0; 00101 00102 //: Compute the geometric error distance between two features. 00103 virtual 00104 double geometric_error( rgrl_feature const& mapped_other ) const; 00105 00106 //: Compute the geometric error distance between two features. 00107 // Use this function for efficiency. 00108 // If a mapped feature is created, use the other function 00109 virtual 00110 double geometric_error( rgrl_transformation const& xform, 00111 rgrl_feature const& other ) const; 00112 00113 //: When computing geometric error, allow only mapping of From location 00114 // Otherwise, a mapped feature will be created, which is much more heavy 00115 virtual 00116 bool allow_fast_computation_on_error() const { return true; } 00117 00118 //: Compute the signature error vector between two features. 00119 // 00120 // The result is invalid if signature_error_dimension() is false (0). 00121 // 00122 // A signature vector stores a set of properties associated with the 00123 // feature. Take the trace point on a vessel for example. The 00124 // possible properties include the normal to the vessel and the 00125 // vessel width at the give trace point. A feature can return 00126 // different type of signature_error_vector, depending on the type 00127 // of the \a other feature. 00128 // 00129 // A signature_error_vector describes the "difference" between two 00130 // features. It is important for the computation of robust 00131 // signature/similarity weight. The robust weight depends on the 00132 // weight distribution of all matches involved in the estimation of 00133 // the transformation. 00134 // 00135 // CAVEAT: We assume the signature_error_vector has zero-mean. 00136 // 00137 virtual vnl_vector<double> signature_error_vector( rgrl_feature const& other ) const; 00138 00139 //: If non-zero, the dimensions of the signature error vector. 00140 // 00141 // The dimension depends on the \a other feature type. Defaults to 0. 00142 // 00143 virtual unsigned signature_error_dimension( const vcl_type_info& other_feature_type ) const; 00144 00145 //: Compute the signature weight between two features. 00146 // 00147 // The weight is determined solely based on the current and \a other 00148 // features. In other words, it is independent of the 00149 // signature/similarity weight distribution of all matches involved 00150 // in the estimation of the transformation. It is often independent 00151 // of the \a signature_error_vector. Defaults to 1. 00152 // 00153 virtual double absolute_signature_weight( rgrl_feature_sptr /*other*/ ) const 00154 { return 1.0; } 00155 00156 // Defines type-related functions 00157 rgrl_type_macro( rgrl_feature, rgrl_object ); 00158 00159 //: make a clone copy 00160 virtual rgrl_feature_sptr clone() const=0; 00161 00162 protected: 00163 // friend rgrl_feature_sptr 00164 // rgrl_feature_reader( vcl_istream& is ); 00165 friend class rgrl_feature_reader; 00166 00167 vnl_vector<double> location_; 00168 double scale_; 00169 00170 private: 00171 // disabled 00172 rgrl_feature& operator=( rgrl_feature const& ); 00173 }; 00174 00175 00176 //: Down cast from rgrl_feature_sptr. 00177 // 00178 // This does a dynamic_cast and then asserts that the result is not 00179 // null. Therefore, you are guaranteed that the result is a valid 00180 // pointer, or else the program will halt. 00181 // 00182 // \code 00183 // rgrl_feature_sptr ptr; 00184 // rgrl_feature_landmark* real_ptr = rgrl_feature_caster<rgrl_feature_landmark>(ptr); 00185 // \endcode 00186 template<class CastTo> 00187 class rgrl_feature_caster 00188 { 00189 public: 00190 rgrl_feature_caster( rgrl_feature_sptr f ) 00191 : data_( dynamic_cast<CastTo*>( f.as_pointer() ) ) { assert( data_ ); } 00192 00193 operator CastTo*() const { return data_; } 00194 CastTo* operator ->() const { return data_; } 00195 private: 00196 CastTo* data_; 00197 }; 00198 00199 #endif