/vol/vipdata/irtk/packages/transformation/include/irtkBSplineFreeFormTransformation3D.h

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkBSplineFreeFormTransformation3D.h 2 2008-12-23 12:40:14Z dr $
00005   Copyright : Imperial College, Department of Computing
00006               Visual Information Processing (VIP), 2008 onwards
00007   Date      : $Date: 2008-12-23 12:40:14 +0000 (Tue, 23 Dec 2008) $
00008   Version   : $Revision: 2 $
00009   Changes   : $Author: dr $
00010 
00011 =========================================================================*/
00012 
00013 #ifndef _IRTKBSPLINEFREEFORMTRANSFORMATION3D_H
00014 
00015 #define _IRTKBSPLINEFREEFORMTRANSFORMATION3D_H
00016 
00017 #include <irtkGeometry.h>
00018 
00028 class irtkBSplineFreeFormTransformation3D : public irtkFreeFormTransformation3D
00029 {
00030 
00031   friend class irtkLinearFreeFormTransformation;
00032 
00033 protected:
00034 
00036   static double B0(double);
00037 
00039   static double B1(double);
00040 
00042   static double B2(double);
00043 
00045   static double B3(double);
00046 
00048   static double B0_I(double);
00049 
00051   static double B1_I(double);
00052 
00054   static double B2_I(double);
00055 
00057   static double B3_I(double);
00058 
00060   static double B0_II(double);
00061 
00063   static double B1_II(double);
00064 
00066   static double B2_II(double);
00067 
00069   static double B3_II(double);
00070 
00072   virtual void Subdivide2D();
00073 
00075   virtual void Subdivide3D();
00076 
00078   static double InitialAntiCausalCoefficient(double *, int, double z);
00079 
00081   static double InitialCausalCoefficient(double *, int, double, double);
00082 
00084   static void ConvertToInterpolationCoefficients(double* c, int DataLength, double* z, int NbPoles, double Tolerance);
00085 
00088   void ComputeCoefficients(double* dxs, double* dys, double* dzs, irtkRealImage& xCoeffs, irtkRealImage& yCoeffs, irtkRealImage& zCoeffs);
00089 
00091   static    double LookupTable[FFDLOOKUPTABLESIZE][4];
00092 
00093   /* Memory for lookup table for first derivatives of B-spline basis
00094    * function values */
00095   static    double LookupTable_I[FFDLOOKUPTABLESIZE][4];
00096 
00097   /* Memory for lookup table for second derivatives of B-spline basis
00098    * function values */
00099   static    double LookupTable_II[FFDLOOKUPTABLESIZE][4];
00100 
00101 public:
00102 
00104   static double B (int, double);
00105 
00107   static double B_I(int, double);
00108 
00110   static double B_II(int, double);
00111 
00113   irtkBSplineFreeFormTransformation3D();
00114 
00116   irtkBSplineFreeFormTransformation3D(irtkBaseImage &, double = 1, double = 1, double = 1);
00117 
00119   irtkBSplineFreeFormTransformation3D(double x1, double y1, double z1,
00120                                       double x2, double y2, double z2,
00121                                       double dx, double dy, double dz,
00122                                       double* xaxis, double* yaxis, double* zaxis);
00123 
00125   irtkBSplineFreeFormTransformation3D(const class irtkBSplineFreeFormTransformation3D &);
00126 
00128   virtual ~irtkBSplineFreeFormTransformation3D();
00129 
00134   virtual double Approximate(double *, double *, double *,
00135                              double *, double *, double *, int);
00136 
00143   virtual void Interpolate(double* dxs, double* dys, double* dzs);
00144 
00146   virtual void Subdivide();
00147 
00149   virtual void FFD1(double &, double &, double &) const;
00150 
00152   virtual void FFD2(double &, double &, double &) const;
00153 
00155   virtual void Transform(double &, double &, double &, double = 0);
00156 
00158   virtual void Transform2(double &, double &, double &, double = 0);
00159 
00161   virtual void GlobalTransform(double &, double &, double &, double = 0);
00162 
00164   virtual void LocalTransform (double &, double &, double &, double = 0);
00165 
00167   virtual void GlobalDisplacement(double &, double &, double &, double = 0);
00168 
00170   virtual void LocalDisplacement(double &, double &, double &, double = 0);
00171 
00173   virtual void Jacobian(irtkMatrix &, double, double, double, double = 0);
00174 
00176   virtual void LocalJacobian(irtkMatrix &, double, double, double, double = 0);
00177 
00179   virtual void GlobalJacobian(irtkMatrix &, double, double, double, double = 0);
00180 
00182   virtual double Bending(double x, double y, double z);
00183 
00188   virtual void BoundingBox(int, irtkPoint &, irtkPoint &, double = 1) const;
00189 
00194   virtual void BoundingBox(int, double &, double &, double &,
00195                            double &, double &, double &, double = 1) const;
00196 
00201   virtual void BoundingBox(irtkGreyImage *, int, int &, int &, int &,
00202                            int &, int &, int &, double = 1) const;
00203 
00205   virtual void Print();
00206 
00208   static int CheckHeader(char *);
00209 
00211   virtual const char *NameOfClass();
00212 
00214   virtual irtkCifstream& Read(irtkCifstream&);
00215 
00217   virtual irtkCofstream& Write(irtkCofstream&);
00218 
00220   virtual istream& Import(istream&);
00221 
00223   virtual ostream& Export(ostream&);
00224 
00225 };
00226 
00227 inline double irtkBSplineFreeFormTransformation3D::B(int i, double t)
00228 {
00229   switch (i) {
00230   case 0:
00231     return (1-t)*(1-t)*(1-t)/6.0;
00232   case 1:
00233     return (3*t*t*t - 6*t*t + 4)/6.0;
00234   case 2:
00235     return (-3*t*t*t + 3*t*t + 3*t + 1)/6.0;
00236   case 3:
00237     return (t*t*t)/6.0;
00238   }
00239   return 0;
00240 }
00241 
00242 inline double irtkBSplineFreeFormTransformation3D::B_I(int i, double t)
00243 {
00244   switch (i) {
00245   case 0:
00246     return -(1-t)*(1-t)/2.0;
00247   case 1:
00248     return (9*t*t - 12*t)/6.0;
00249   case 2:
00250     return (-9*t*t + 6*t + 3)/6.0;
00251   case 3:
00252     return (t*t)/2.0;
00253   }
00254   return 0;
00255 }
00256 
00257 inline double irtkBSplineFreeFormTransformation3D::B_II(int i, double t)
00258 {
00259   switch (i) {
00260   case 0:
00261     return 1 - t;
00262   case 1:
00263     return 3*t - 2;
00264   case 2:
00265     return -3*t + 1;
00266   case 3:
00267     return t;
00268   }
00269   return 0;
00270 }
00271 
00272 inline double irtkBSplineFreeFormTransformation3D::B0(double t)
00273 {
00274   return (1-t)*(1-t)*(1-t)/6.0;
00275 }
00276 
00277 inline double irtkBSplineFreeFormTransformation3D::B1(double t)
00278 {
00279   return (3*t*t*t - 6*t*t + 4)/6.0;
00280 }
00281 
00282 inline double irtkBSplineFreeFormTransformation3D::B2(double t)
00283 {
00284   return (-3*t*t*t + 3*t*t + 3*t + 1)/6.0;
00285 }
00286 
00287 inline double irtkBSplineFreeFormTransformation3D::B3(double t)
00288 {
00289   return (t*t*t)/6.0;
00290 }
00291 
00292 inline double irtkBSplineFreeFormTransformation3D::B0_I(double t)
00293 {
00294   return -(1-t)*(1-t)/2.0;
00295 }
00296 
00297 inline double irtkBSplineFreeFormTransformation3D::B1_I(double t)
00298 {
00299   return (9*t*t - 12*t)/6.0;
00300 }
00301 
00302 inline double irtkBSplineFreeFormTransformation3D::B2_I(double t)
00303 {
00304   return (-9*t*t + 6*t + 3)/6.0;
00305 }
00306 
00307 inline double irtkBSplineFreeFormTransformation3D::B3_I(double t)
00308 {
00309   return (t*t)/2.0;
00310 }
00311 
00312 inline double irtkBSplineFreeFormTransformation3D::B0_II(double t)
00313 {
00314   return 1 - t;
00315 }
00316 
00317 inline double irtkBSplineFreeFormTransformation3D::B1_II(double t)
00318 {
00319   return 3*t - 2;
00320 }
00321 
00322 inline double irtkBSplineFreeFormTransformation3D::B2_II(double t)
00323 {
00324   return -3*t + 1;
00325 }
00326 
00327 inline double irtkBSplineFreeFormTransformation3D::B3_II(double t)
00328 {
00329   return t;
00330 }
00331 
00332 inline void irtkBSplineFreeFormTransformation3D::Transform(double &x, double &y, double &z, double)
00333 {
00334   double u, v, w;
00335 
00336   u = x;
00337   v = y;
00338   w = z;
00339 
00340   // Convert world coordinates in to FFD coordinates
00341   this->WorldToLattice(u, v, w);
00342 
00343   // Calculate FFD
00344   this->FFD1(u, v, w);
00345 
00346   // Add FFD to world coordinates
00347   x += u;
00348   y += v;
00349   z += w;
00350 }
00351 
00352 inline void irtkBSplineFreeFormTransformation3D::Transform2(double &x, double &y, double &z, double)
00353 {
00354   double u, v, w;
00355 
00356   u = x;
00357   v = y;
00358   w = z;
00359 
00360   // Convert world coordinates in to FFD coordinates
00361   this->WorldToLattice(u, v, w);
00362 
00363   // Calculate FFD
00364   this->FFD2(u, v, w);
00365 
00366   // Add FFD to world coordinates
00367   x += u;
00368   y += v;
00369   z += w;
00370 }
00371 
00372 inline void irtkBSplineFreeFormTransformation3D::GlobalTransform(double &x, double &y, double &z, double)
00373 {}
00374 
00375 inline void irtkBSplineFreeFormTransformation3D::LocalTransform(double &x, double &y, double &z, double)
00376 {
00377   double u, v, w;
00378 
00379   u = x;
00380   v = y;
00381   w = z;
00382 
00383   // calculate displacement
00384   this->LocalDisplacement(u, v, w);
00385 
00386   // Add displacement
00387   x += u;
00388   y += v;
00389   z += w;
00390 }
00391 
00392 inline void irtkBSplineFreeFormTransformation3D::GlobalDisplacement(double &x, double &y, double &z, double)
00393 {
00394   x = 0;
00395   y = 0;
00396   z = 0;
00397 }
00398 
00399 inline void irtkBSplineFreeFormTransformation3D::LocalDisplacement(double &x, double &y, double &z, double)
00400 {
00401   // Convert world coordinates in to FFD coordinates
00402   this->WorldToLattice(x, y, z);
00403 
00404   // Calculate FFD
00405   this->FFD1(x, y, z);
00406 }
00407 
00408 inline const char *irtkBSplineFreeFormTransformation3D::NameOfClass()
00409 {
00410   return "irtkBSplineFreeFormTransformation3D";
00411 }
00412 
00413 #endif