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