contrib/mul/mbl/mbl_thin_plate_spline_3d.h
Go to the documentation of this file.
00001 // This is mul/mbl/mbl_thin_plate_spline_3d.h
00002 #ifndef mbl_thin_plate_spline_3d_h_
00003 #define mbl_thin_plate_spline_3d_h_
00004 //:
00005 // \file
00006 // \brief Construct thin plate spline to map 3D to 3D
00007 // \author Tim Cootes
00008 
00009 #include <vgl/vgl_point_3d.h>
00010 #include <vcl_vector.h>
00011 #include <vnl/vnl_vector.h>
00012 #include <vnl/vnl_matrix.h>
00013 #include <vsl/vsl_binary_io.h>
00014 
00015 //=======================================================================
00016 //: Construct thin plate spline to map 3D to 3D.
00017 // I.e. does some mapping (x',y',z') = f(x,y,z). (See Booksteins work, e.g. IPMI 1993)
00018 // The warp is `guided' by a set of
00019 // landmarks p(0) .. p(n-1) in the source plane which are to be
00020 // mapped to a (possibly deformed) set q(0)..q(n-1) in the destination.
00021 // Thus the mapping is constrained so that f(p(i)) = q(i) for i = 0..n-1.
00022 // The points are given to the build() function to set up the object.
00023 //
00024 // If one wishes to map a set of source points to multiple target points,
00025 // use set_source_pts(src_pts);  then build(target_pts); for each target set.
00026 //
00027 // \code
00028 // vcl_vector<vgl_point_3d<double> > src_pts(n_points),dest_pts(n_points);
00029 //
00030 // // Fill src_pts and dest_pts
00031 // .....
00032 //
00033 // // Construct spline object
00034 // mbl_thin_plate_spline_3d tps;
00035 // tps.build(src_pts,dest_pts);
00036 //
00037 // // Apply to point p:
00038 // vgl_point_3d<double> p(1,2,3);
00039 // vgl_point_3d<double> new_p = tps(p);
00040 // \endcode
00041 class mbl_thin_plate_spline_3d
00042 {
00043   vnl_vector<double> Wx_,Wy_,Wz_;
00044   double Ax0_, AxX_, AxY_, AxZ_;
00045   double Ay0_, AyX_, AyY_, AyZ_;
00046   double Az0_, AzX_, AzY_, AzZ_;
00047   double energy_x_,energy_y_,energy_z_;
00048 
00049   vcl_vector<vgl_point_3d<double> > src_pts_;
00050 
00051   //: Used to estimate weights in set_source_points()
00052   vnl_matrix<double> L_inv_;
00053 
00054   //: Build from small number of points
00055   void build_pure_affine(const vcl_vector<vgl_point_3d<double> >& source_pts,
00056                          const vcl_vector<vgl_point_3d<double> >& dest_pts);
00057 
00058   //: Set parameters from vectors
00059   void set_params(const vnl_vector<double>& W1,
00060                   const vnl_vector<double>& W2,
00061                   const vnl_vector<double>& W3);
00062 
00063   void set_up_rhs(vnl_vector<double>& Bx,
00064                   vnl_vector<double>& By,
00065                   vnl_vector<double>& Bz,
00066                   const vcl_vector<vgl_point_3d<double> >& dest_pts);
00067 
00068   //: Compute spline-bending energy
00069   void compute_energy(vnl_vector<double>& W1,
00070                       vnl_vector<double>& W2,
00071                       vnl_vector<double>& W3,
00072                       const vnl_matrix<double>& L);
00073 
00074  public:
00075 
00076   //: Dflt ctor
00077   mbl_thin_plate_spline_3d();
00078 
00079   //: Destructor
00080   virtual ~mbl_thin_plate_spline_3d();
00081 
00082   //: Sets up internal transformation to map source_pts onto dest_pts
00083   void build(const vcl_vector<vgl_point_3d<double> >& source_pts,
00084              const vcl_vector<vgl_point_3d<double> >& dest_pts,
00085              bool compute_the_energy=false);
00086 
00087   //: Define source point positions
00088   //  Performs pre-computations so that build(dest_points) can be
00089   //  called multiple times efficiently
00090   void set_source_pts(const vcl_vector<vgl_point_3d<double> >& source_pts);
00091 
00092   //: Sets up internal transformation to map source_pts onto dest_pts
00093   void build(const vcl_vector<vgl_point_3d<double> >& dest_pts);
00094 
00095   //: Return transformed version of (x,y,z)
00096   vgl_point_3d<double>  operator()(double x, double y, double z) const;
00097 
00098   //: Return transformed version of (x,y,z)
00099   vgl_point_3d<double>  operator()(const vgl_point_3d<double>&  p) const
00100   { return operator()(p.x(),p.y(),p.z()); }
00101 
00102   //: Bending energy of X component (zero for pure affine)
00103   //  A measure of total amount of non-linear deformation
00104   double bendingEnergyX() const { return energy_x_; }
00105 
00106   //: Bending energy of Y component (zero for pure affine)
00107   //  A measure of total amount of non-linear deformation
00108   double bendingEnergyY() const { return energy_y_; }
00109 
00110   //: Bending energy of Z component (zero for pure affine)
00111   //  A measure of total amount of non-linear deformation
00112   double bendingEnergyZ() const { return energy_z_; }
00113 
00114   //: Version number for I/O
00115   short version_no() const;
00116 
00117   //: Print class to os
00118   void print_summary(vcl_ostream& os) const;
00119 
00120   //: Save class to binary file stream
00121   void b_write(vsl_b_ostream& bfs) const;
00122 
00123   //: Load class from binary file stream
00124   void b_read(vsl_b_istream& bfs);
00125 
00126   //: Comparison operator
00127   bool operator==(const mbl_thin_plate_spline_3d& tps) const;
00128 };
00129 
00130 //: Binary file stream output operator for class reference
00131 void vsl_b_write(vsl_b_ostream& bfs, const mbl_thin_plate_spline_3d& b);
00132 
00133 //: Binary file stream input operator for class reference
00134 void vsl_b_read(vsl_b_istream& bfs, mbl_thin_plate_spline_3d& b);
00135 
00136 //: Stream output operator for class reference
00137 vcl_ostream& operator<<(vcl_ostream& os,const mbl_thin_plate_spline_3d& b);
00138 
00139 #endif
00140 
00141