contrib/rpl/rgrl/rgrl_feature.h
Go to the documentation of this file.
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