contrib/rpl/rgrl/rgrl_transformation.h
Go to the documentation of this file.
00001 #ifndef rgrl_transformation_h_
00002 #define rgrl_transformation_h_
00003 //:
00004 // \file
00005 // \brief Base class for transformation representation, estimations and application in generalized registration library
00006 // \author Chuck Stewart
00007 // \date 15 Nov 2002
00008 
00009 #include <vnl/vnl_vector.h>
00010 #include <vnl/vnl_matrix.h>
00011 #include <vcl_iosfwd.h>
00012 
00013 #include <rgrl/rgrl_object.h>
00014 #include <rgrl/rgrl_set_of.h>
00015 #include <rgrl/rgrl_match_set_sptr.h>
00016 
00017 #include <rgrl/rgrl_transformation_sptr.h>
00018 
00019 //: A base class that represents a transformation.
00020 //
00021 // Derived classes must implement
00022 // - map_loc() to map a location
00023 // - map_dir() to map a direction
00024 // - covar() to provide the parameter covariance matrix
00025 //
00026 // We use different names for the functions that derived classes
00027 // implement because otherwise the "name hiding rule" of the C++
00028 // standard is invoked, which means the some of the functionality in
00029 // the base class interface--in particular, the overloaded
00030 // convenience functions--are unavailable in the derived class
00031 // interface.
00032 //
00033 class rgrl_transformation
00034   : public rgrl_object
00035 {
00036  public:
00037   virtual ~rgrl_transformation();
00038 
00039   //: default constructor
00040   rgrl_transformation() :  is_covar_set_(false) {  }
00041 
00042   //: initialize with covariance matrix
00043   rgrl_transformation( const vnl_matrix<double>& cov );
00044 
00045   //: Apply the transformation to create a new (mapped) location
00046   void map_location( vnl_vector<double> const& from,
00047                      vnl_vector<double>      & to    ) const;
00048 
00049   //:  Apply the transformation to create a new (mapped) location
00050   //
00051   // Convenience call to the two parameter version that allocates the
00052   // result vector.
00053   //
00054   vnl_vector<double> map_location( vnl_vector<double> const& p ) const;
00055 
00056   //: Map a tangent direction
00057   //
00058   // The resulting direction \a to_dir is a unit vector.
00059   //
00060   virtual void map_tangent( vnl_vector<double> const& from_loc,
00061                             vnl_vector<double> const& from_dir,
00062                             vnl_vector<double>      & to_dir    ) const;
00063 
00064   //: Map a normal direction
00065   //
00066   // The resulting direction \a to_dir is a unit vector.
00067   //
00068   virtual void map_normal( vnl_vector<double> const & from_loc,
00069                            vnl_vector<double> const & from_dir,
00070                            vnl_vector<double>       & to_dir    ) const;
00071 
00072   //: Map a normal direction, given the tangent subspace
00073   //
00074   // The resulting direction \a to_dir is a unit vector.
00075   //
00076   virtual void map_normal( vnl_vector<double> const  & from_loc,
00077                            vnl_vector<double> const  & from_dir,
00078                            vnl_matrix< double > const& tangent_subspace,
00079                            vnl_vector<double>        & to_dir    ) const;
00080 
00081 
00082   //: Map an arbitrary direction which is neither a tangent nor a normal
00083   //
00084   // The resulting direction \a to_dir is a unit vector.
00085   //
00086   void map_direction( vnl_vector<double> const& from_loc,
00087                       vnl_vector<double> const& from_dir,
00088                       vnl_vector<double>      & to_dir    ) const;
00089 
00090 #if 0
00091   // Don't provide this interface because it is quite easy to confuse
00092   // it with the three vector version. If you intended to call the
00093   // three vector version, but forget to provide the location, then
00094   // the compiler will simply call this version and there will be no
00095   // error; just wrong results.
00096   vnl_vector<double> map_direction( vnl_vector<double> const& from_loc,
00097                                     vnl_vector<double> const& from_dir ) const;
00098 #endif // 0
00099 
00100   //:  Apply to an intensity, with a default of the identity.
00101   virtual
00102   double map_intensity( vnl_vector<double> const& from, double intensity ) const;
00103 
00104   //:  Compute covariance of the transfer error based on transformation covariance
00105   //
00106   // This gives the additional uncertainty of the transferred point
00107   // location due to the uncertainty of the transform estimate.
00108   //
00109   virtual
00110   vnl_matrix<double> transfer_error_covar( vnl_vector<double> const& p ) const = 0;
00111 
00112 
00113   //:  Inverse map with an initial guess
00114   virtual void inv_map( const vnl_vector<double>& to,
00115                         bool initialize_next,
00116                         const vnl_vector<double>& to_delta,
00117                         vnl_vector<double>& from,
00118                         vnl_vector<double>& from_next_est) const;
00119 
00120   //:  Parameter covariance matrix
00121   vnl_matrix<double> covar() const;
00122 
00123   //: log of determinant of the covariance
00124   virtual double
00125   log_det_covar() const;
00126   
00127   //:  set parameter covariance matrix
00128   void set_covar( const vnl_matrix<double>& covar );
00129 
00130   //: is covariance set?
00131   bool is_covar_set() const { return is_covar_set_; }
00132 
00133   //:  Inverse map based on the transformation.
00134   //   This function only exist for certain transformations.
00135   virtual void inv_map( const vnl_vector<double>& to,
00136                         vnl_vector<double>& from ) const;
00137 
00138   //: is this an invertible transformation?
00139   virtual bool is_invertible() const { return false; }
00140 
00141   //: Return an inverse transformation
00142   //  This function only exist for certain transformations.
00143   virtual rgrl_transformation_sptr inverse_transform() const;
00144 
00145   //: Return the jacobian of the transform
00146   //  use only as backward compatibility
00147   vnl_matrix<double> jacobian( vnl_vector<double> const& from_loc ) const;
00148                                                                                       
00149   //: Compute jacobian w.r.t. location
00150   virtual void jacobian_wrt_loc( vnl_matrix<double>& jac, vnl_vector<double> const& from_loc ) const = 0;
00151   
00152   //:  transform the transformation for images of different resolution
00153   virtual rgrl_transformation_sptr scale_by( double scale ) const = 0;
00154 
00155   //: output transformation
00156   virtual void write( vcl_ostream& os ) const;
00157 
00158   //: input transformation
00159   virtual bool read( vcl_istream& is );
00160 
00161   //: make a clone copy
00162   virtual rgrl_transformation_sptr clone() const=0;
00163 
00164   //: set scaling factors
00165   //  Unless the transformation is not estimated using estimators in rgrl,
00166   //  it does not need to be set explicitly
00167   void set_scaling_factors( vnl_vector<double> const& scaling );
00168 
00169   //: return scaling factor
00170   const vnl_vector<double>& scaling_factors() const { return scaling_factors_; }
00171 
00172   // Defines type-related functions
00173   rgrl_type_macro( rgrl_transformation, rgrl_object );
00174 
00175 
00176  protected:
00177 
00178   //:  Apply the transformation to create a new (mapped) location
00179   //
00180   virtual
00181   void map_loc( vnl_vector<double> const& from,
00182                 vnl_vector<double>      & to    ) const = 0;
00183 
00184   //:  Apply the transformation to create a new direction at the (mapped) location
00185   //
00186   // The resulting direction \a to_dir is a unit vector.
00187   //
00188   virtual
00189   void map_dir( vnl_vector<double> const& from_loc,
00190                 vnl_vector<double> const& from_dir,
00191                 vnl_vector<double>      & to_dir    ) const = 0;
00192 
00193   //: a slightly better way of computing log of determinant
00194   double
00195   log_det_sym_matrix( vnl_matrix<double> const& m ) const;
00196   
00197   //: compute the log of determinant of the covariance when the matrix is rank deficient
00198   double
00199   log_det_covar_deficient( int rank ) const;
00200   
00201  protected:
00202 
00203   //: covariance matrix
00204   //  Unlike transformation parameters, covariance is always a mtrix of double.
00205   vnl_matrix<double> covar_;
00206 
00207   //: flag of setting covariance
00208   //  Check it before using covariance matrix
00209   bool is_covar_set_;
00210 
00211   //: scaling factors of current transformation on each dimension
00212   //  This is computed from current transformation.
00213   //  And it has nothing to do with how to transform points
00214   vnl_vector<double> scaling_factors_;
00215 };
00216 
00217 vcl_ostream&
00218 operator<< (vcl_ostream& os, rgrl_transformation const& xform );
00219 
00220 #endif