21 #ifndef MIRTK_FreeFormTransformation_H    22 #define MIRTK_FreeFormTransformation_H    24 #include "mirtk/Transformation.h"    26 #include "mirtk/Math.h"    27 #include "mirtk/Memory.h"    28 #include "mirtk/Vector3D.h"    29 #include "mirtk/InterpolateImageFunction.h"    30 #include "mirtk/ExtrapolateImageFunction.h"    31 #include "mirtk/TransformationJacobian.h"    32 #include "mirtk/ImageFunction.h"    64                                            double, 
double, 
double, 
double,
    65                                            double, 
double, 
double, 
double,
    66                                            const double *, 
const double *,
   132   CPInterpolator *_CPFunc2D; 
   175                          CPInterpolator &, CPInterpolator * = NULL);
   189   void Initialize(
const CPImage &, 
bool = 
false);
   201   virtual bool Set(
const char *, 
const char *);
   234                              int = 1, 
double = .0);
   240   virtual double Approximate(
const double *, 
const double *, 
const double *,
   241                              double *,       
double *,       
double *, 
int,
   242                              int = 1, 
double = .0);
   248   virtual double Approximate(
const double *, 
const double *, 
const double *, 
const double *,
   249                              double *,       
double *,       
double *,       
int,
   250                              int = 1, 
double = .0);
   260                                   int = 1, 
double = .0);
   264   virtual void Interpolate(
const double *, 
const double *, 
const double *) = 0;
   322   void GetSpacing(
double &, 
double &, 
double &) 
const;
   325   void GetSpacing(
double &, 
double &, 
double &, 
double &) 
const;
   361   void IndexToWorld(
int, 
double &, 
double &, 
double &) 
const;
   427   virtual void Subdivide(
bool = 
true, 
bool = 
true, 
bool = 
true, 
bool = 
true);
   459                       double, 
double, 
double);
   469                       double, 
double, 
double, 
double);
   476                    double &, 
double &, 
double &) 
const;
   482   void BoundingBox(
double &, 
double &, 
double &, 
double &,
   483                    double &, 
double &, 
double &, 
double &) 
const;
   491   virtual void BoundingBox(
int, 
double &, 
double &, 
double = 1) 
const;
   496   virtual void BoundingBox(
int, 
double &, 
double &, 
double &,
   497                                 double &, 
double &, 
double &, 
double = 1) 
const = 0;
   502   virtual void BoundingBox(
int, 
double &, 
double &, 
double &, 
double &,
   503                                 double &, 
double &, 
double &, 
double &, 
double = 1) 
const;
   514                                                  int &, 
int &, 
int &, 
double = 1) 
const;
   520                                                  int &, 
int &, 
int &, 
int &, 
double = 1) 
const;
   526                                                     int &, 
int &, 
int &, 
double = 1) 
const;
   532                                        int &, 
int &, 
int &, 
double = 1) 
const;
   538                                        int &, 
int &, 
int &, 
int &, 
double = 1) 
const;
   544                                           int &, 
int &, 
int &, 
double = 1) 
const;
   561   void Put(
int, 
const Vector &);
   564   void Put(
int, 
double, 
double, 
double);
   567   void Put(
int, 
int, 
int, 
double, 
double, 
double);
   570   void Put(
int, 
int, 
int, 
int, 
double, 
double, 
double);
   573   void Get(
int, Vector &) 
const;
   576   void Get(
int, 
double &, 
double &, 
double &) 
const;
   579   void Get(
int, 
int, 
int, 
double &, 
double &, 
double &) 
const;
   582   void Get(
int, 
int, 
int, 
int, 
double &, 
double &, 
double &) 
const;
   606   virtual bool IsActive(
int, 
int, 
int = 0, 
int = 0) 
const;
   614   virtual void GlobalTransform(
double &, 
double &, 
double &, 
double = 0, 
double = NaN) 
const;
   617   virtual void Transform(
double &, 
double &, 
double &, 
double = 0, 
double = NaN) 
const;
   620   virtual void GlobalInverse(
double &, 
double &, 
double &, 
double = 0, 
double = NaN) 
const;
   623   virtual bool Inverse(
double &, 
double &, 
double &, 
double = 0, 
double = NaN) 
const;
   656   void HessianToWorld(
double &, 
double &, 
double &, 
double &, 
double &, 
double &) 
const;
   673   virtual void Jacobian(
Matrix &, 
double, 
double, 
double, 
double = 0, 
double = NaN) 
const;
   676   virtual void GlobalHessian(
Matrix [3], 
double, 
double, 
double, 
double = 0, 
double = NaN) 
const;
   679   virtual void Hessian(
Matrix [3], 
double, 
double, 
double, 
double = 0, 
double = NaN) 
const;
   682   virtual void JacobianDOFs(
Matrix &, 
int, 
double, 
double, 
double, 
double = 0, 
double = NaN) 
const;
   702                                         int cp, 
double x, 
double y, 
double z, 
double = 0, 
double = NaN,
   703                                         bool wrt_world = 
true, 
bool use_spacing = 
true) 
const;
   718                                      int cp, 
double x, 
double y, 
double z, 
double t = 0, 
double t0 = NaN,
   719                                      bool wrt_world = 
true, 
bool use_spacing = 
true) 
const;
   739                                   double = NaN, 
double = 1) 
const;
   744                                   double *, 
double = 0, 
double = NaN, 
double = 1) 
const;
   753   virtual double BendingEnergy(
double, 
double, 
double, 
double = 0, 
double = NaN, 
bool = 
true) 
const;
   756   virtual double BendingEnergy(
bool = 
false, 
bool = 
true) 
const;
   763   virtual void BendingEnergyGradient(
double *, 
double = 1.0, 
bool = 
false, 
bool = 
true, 
bool = 
true) 
const;
  1072   x = i, y = j, z = k;
  1091   return this->
GetX();
  1097   return this->
GetY();
  1103   return this->
GetZ();
  1109   return this->
GetT();
  1139   if (subdivide_x || subdivide_y || subdivide_z || subdivide_t) {
  1140     cerr << this->
NameOfClass() << 
"::Subdivide: Not implemented (or not possible?)" << endl;
  1148   this->
Subdivide(
true, 
true, 
false, 
false);
  1154   this->
Subdivide(
true, 
true, 
true, 
false);
  1160   this->
Subdivide(
true, 
true, 
true, 
true);
  1172   if (t1 > t2) swap(t1, t2);
  1177                                                 double &x2, 
double &y2, 
double &z2)
 const  1181   x2 = 
_x - 1, y2 = 
_y - 1, z2 = 
_z - 1;
  1183   if (x1 > x2) swap(x1, x2);
  1184   if (y1 > y2) swap(y1, y2);
  1185   if (z1 > z2) swap(z1, z2);
  1196                                                 double &x2, 
double &y2, 
double &z2, 
double &t2)
 const  1213   if (t1 > t2) swap(t1, t2);
  1218                                                      double &x2, 
double &y2, 
double &z2, 
double)
 const  1220   x1 = 0,      y1 = 0,      z1 = 0;
  1221   x2 = 
_x - 1, y2 = 
_y - 1, z2 = 
_z - 1;
  1224   if (x1 > x2) swap(x1, x2);
  1225   if (y1 > y2) swap(y1, y2);
  1226   if (z1 > z2) swap(z1, z2);
  1231                                                         double &x2, 
double &y2, 
double &z2, 
double &t2,
  1232                                                         double fraction)
 const  1234   this->
BoundingBox(cp, x1, y1, z1, x2, y2, z2, fraction);
  1246                                                 int &i1, 
int &j1, 
int &k1,
  1247                                                 int &i2, 
int &j2, 
int &k2,
  1248                                                 double fraction)
 const  1251   double x[2], y[2], z[2];
  1252   this->
BoundingBox(cp, x[0], y[0], z[0], x[1], y[1], z[1], fraction);
  1257   double x1, y1, z1, x2, y2, z2;
  1258   x1 = y1 = z1 = + 
inf;
  1259   x2 = y2 = z2 = - 
inf;
  1261   for (
int c = 0; c <= 1; ++c)
  1262   for (
int b = 0; b <= 1; ++b)
  1263   for (
int a = 0; a <= 1; ++a) {
  1264     p = 
Point(x[a], y[b], z[c]);
  1266     if (p.
_x < x1) x1 = p.
_x;
  1267     if (p.
_x > x2) x2 = p.
_x;
  1268     if (p.
_y < y1) y1 = p.
_y;
  1269     if (p.
_y > y2) y2 = p.
_y;
  1270     if (p.
_z < z1) z1 = p.
_z;
  1271     if (p.
_z > z2) z2 = p.
_z;
  1286   i1 = (i1 < 0 ?  0 : (i1 >= domain.
X() ? domain.
X()     : i1));
  1287   i2 = (i2 < 0 ? -1 : (i2 >= domain.
X() ? domain.
X() - 1 : i2));
  1288   j1 = (j1 < 0 ?  0 : (j1 >= domain.
Y() ? domain.
Y()     : j1));
  1289   j2 = (j2 < 0 ? -1 : (j2 >= domain.
Y() ? domain.
Y() - 1 : j2));
  1290   k1 = (k1 < 0 ?  0 : (k1 >= domain.
Z() ? domain.
Z()     : k1));
  1291   k2 = (k2 < 0 ? -1 : (k2 >= domain.
Z() ? domain.
Z() - 1 : k2));
  1292   return i1 <= i2 && j1 <= j2 && k1 <= k2;
  1297                                                 int &i1, 
int &j1, 
int &k1,
  1298                                                 int &i2, 
int &j2, 
int &k2,
  1299                                                 double fraction)
 const  1306                                                 int &i1, 
int &j1, 
int &k1, 
int &l1,
  1307                                                 int &i2, 
int &j2, 
int &k2, 
int &l2,
  1308                                                 double fraction)
 const  1311   bool bbvalid = 
BoundingBox(domain, cp, i1, j1, k1, i2, j2, k2, fraction);
  1320   if (t2 < t1) swap(t1, t2);
  1330   l1 = (l1 < 0 ?  0 : (l1 >= domain.
T() ? domain.
T()     : l1));
  1331   l2 = (l2 < 0 ? -1 : (l2 >= domain.
T() ? domain.
T() - 1 : l2));
  1332   return bbvalid && l1 <= l2;
  1337                                                 int &i1, 
int &j1, 
int &k1, 
int &l1,
  1338                                                 int &i2, 
int &j2, 
int &k2, 
int &l2,
  1339                                                 double fraction)
 const  1341   return BoundingBox(image->
Attributes(), cp, i1, j1, k1, l1, i2, j2, k2, l2, fraction);
  1346                                                    int &i1, 
int &j1, 
int &k1,
  1347                                                    int &i2, 
int &j2, 
int &k2,
  1348                                                    double fraction)
 const  1355                                                    int &i1, 
int &j1, 
int &k1,
  1356                                                    int &i2, 
int &j2, 
int &k2,
  1357                                                    double fraction)
 const  1369   double norm, max = .0;
  1372   for (
int cp = 0; cp < ncps; ++cp) {
  1374     norm = sqrt(gradient[x] * gradient[x] + gradient[y] * gradient[y] + gradient[z] * gradient[z]);
  1375     if (norm > max) max = norm;
  1406                                         double x, 
double y, 
double z)
  1413                                         double x, 
double y, 
double z)
  1415   Put(i, j, k, 0, x, y, z);
  1428   x = param.
_x, y = param.
_y, z = param.
_z;
  1433                                         double &x, 
double &y, 
double &z)
 const  1436   x = param.
_x, y = param.
_y, z = param.
_z;
  1441                                         double &x, 
double &y, 
double &z)
 const  1443   Get(i, j, k, 0, x, y, z);
  1499   return status.
_x == Active || status.
_y == Active || status.
_z == Active;
  1506   return status.
_x == Active || status.
_y == Active || status.
_z == Active;
  1555   du = dx, dv = dy, dw = dz;
  1561   if (jac.
Rows() == 2) {
  1585   du = dx, dv = dy, dw = dz;
  1594   const double &dudx = 
_matW2L(0, 0);
  1595   const double &dudy = 
_matW2L(0, 1);
  1596   const double &dvdx = 
_matW2L(1, 0);
  1597   const double &dvdy = 
_matW2L(1, 1);
  1600   double du, dv, dxx, dxy, dyy;
  1601   du  = duu * dudx + duv * dvdx;
  1602   dv  = duv * dudx + dvv * dvdx;
  1603   dxx = du  * dudx + dv  * dvdx;
  1604   dxy = du  * dudy + dv  * dvdy;
  1605   du  = duu * dudy + duv * dvdy;
  1606   dv  = duv * dudy + dvv * dvdy;
  1607   dyy = du  * dudy + dv  * dvdy;
  1609   duu = dxx, duv = dxy, dvv = dyy;
  1615                                                     double &dvv, 
double &dvw,
  1620   const double &dudx = 
_matW2L(0, 0);
  1621   const double &dudy = 
_matW2L(0, 1);
  1622   const double &dudz = 
_matW2L(0, 2);
  1623   const double &dvdx = 
_matW2L(1, 0);
  1624   const double &dvdy = 
_matW2L(1, 1);
  1625   const double &dvdz = 
_matW2L(1, 2);
  1626   const double &dwdx = 
_matW2L(2, 0);
  1627   const double &dwdy = 
_matW2L(2, 1);
  1628   const double &dwdz = 
_matW2L(2, 2);
  1631   double du, dv, dw, dxx, dxy, dxz, dyy, dyz, dzz;
  1632   du  = duu * dudx + duv * dvdx + duw * dwdx;
  1633   dv  = duv * dudx + dvv * dvdx + dvw * dwdx;
  1634   dw  = duw * dudx + dvw * dvdx + dww * dwdx;
  1635   dxx = du  * dudx + dv  * dvdx + dw  * dwdx;
  1636   dxy = du  * dudy + dv  * dvdy + dw  * dwdy;
  1637   dxz = du  * dudz + dv  * dvdz + dw  * dwdz;
  1638   du  = duu * dudy + duv * dvdy + duw * dwdy;
  1639   dv  = duv * dudy + dvv * dvdy + dvw * dwdy;
  1640   dw  = duw * dudy + dvw * dvdy + dww * dwdy;
  1641   dyy = du  * dudy + dv  * dvdy + dw  * dwdy;
  1642   dyz = du  * dudz + dv  * dvdz + dw  * dwdz;
  1643   du  = duu * dudz + duv * dvdz + duw * dwdz;
  1644   dv  = duv * dudz + dvv * dvdz + dvw * dwdz;
  1645   dw  = duw * dudz + dvw * dvdz + dww * dwdz;
  1646   dzz = du  * dudz + dv  * dvdz + dw  * dwdz;
  1648   duu = dxx, duv = dxy, duw = dxz, dvv = dyy, dvw = dyz, dww = dzz;
  1654   if (hessian.
Rows() == 2) {
  1656     hessian(1, 0) = hessian(0, 1);
  1659                    hessian(1, 1), hessian(1, 2),
  1661     hessian(1, 0) = hessian(0, 1);
  1662     hessian(2, 0) = hessian(0, 2);
  1663     hessian(2, 1) = hessian(1, 2);
  1678   Throw(ERR_NotImplemented, __FUNCTION__, 
"Not implemented");
  1715   int xdof, ydof, zdof;
  1725     jac(0, 0) = dofgrad[0];
  1726     jac(1, 0) = dofgrad[1];
  1727     jac(2, 0) = dofgrad[2];
  1732     jac(0, 1) = dofgrad[0];
  1733     jac(1, 1) = dofgrad[1];
  1734     jac(2, 1) = dofgrad[2];
  1739     jac(0, 2) = dofgrad[0];
  1740     jac(1, 2) = dofgrad[1];
  1741     jac(2, 2) = dofgrad[2];
  1748   int xdof, ydof, zdof;
  1757       if (dofgrad[0] != .0 && dofgrad[1] != .0 && dofgrad[2] != .0) {
  1759         xdofgrad.
_x = dofgrad[0];
  1760         xdofgrad.
_y = dofgrad[1];
  1761         xdofgrad.
_z = dofgrad[2];
  1767       if (dofgrad[0] != .0 && dofgrad[1] != .0 && dofgrad[2] != .0) {
  1769         ydofgrad.
_x = dofgrad[0];
  1770         ydofgrad.
_y = dofgrad[1];
  1771         ydofgrad.
_z = dofgrad[2];
  1777       if (dofgrad[0] != .0 && dofgrad[1] != .0 && dofgrad[2] != .0) {
  1779         zdofgrad.
_x = dofgrad[0];
  1780         zdofgrad.
_y = dofgrad[1];
  1781         zdofgrad.
_z = dofgrad[2];
  1790                         int cp, 
double x, 
double y, 
double z, 
double t, 
double t0,
  1791                         bool wrt_world, 
bool use_spacing)
 const  1803   const Matrix &hx = hessian[0];
  1804   const Matrix &hy = hessian[1];
  1805   const Matrix &hz = hessian[2];
  1807   const double &x_ii = hx(0, 0);
  1808   const double &x_ij = hx(0, 1);
  1809   const double &x_ik = hx(0, 2);
  1810   const double &x_jj = hx(1, 1);
  1811   const double &x_jk = hx(1, 2);
  1812   const double &x_kk = hx(2, 2);
  1814   const double &y_ii = hy(0, 0);
  1815   const double &y_ij = hy(0, 1);
  1816   const double &y_ik = hy(0, 2);
  1817   const double &y_jj = hy(1, 1);
  1818   const double &y_jk = hy(1, 2);
  1819   const double &y_kk = hy(2, 2);
  1821   const double &z_ii = hz(0, 0);
  1822   const double &z_ij = hz(0, 1);
  1823   const double &z_ik = hz(0, 2);
  1824   const double &z_jj = hz(1, 1);
  1825   const double &z_jk = hz(1, 2);
  1826   const double &z_kk = hz(2, 2);
  1828   return         (  x_ii * x_ii + x_jj * x_jj + x_kk * x_kk
  1829                   + y_ii * y_ii + y_jj * y_jj + y_kk * y_kk
  1830                   + z_ii * z_ii + z_jj * z_jj + z_kk * z_kk)
  1831          + 2.0 * (  x_ij * x_ij + x_ik * x_ik + x_jk * x_jk
  1832                   + y_ij * y_ij + y_ik * y_ik + y_jk * y_jk
  1833                   + z_ij * z_ij + z_ik * z_ik + z_jk * z_jk);
  1839 #endif // MIRTK_FreeFormTransformation_H 
double _xaxis[3]
Direction of x-axis. 
 
void WorldToLattice(double &, double &, double &) const
Convert world to lattice coordinate. 
 
int VoxelToIndex(int, int, int=0, int=0) const
Function to convert pixel to index. 
 
const ImageAttributes & Attributes() const
Gets the image attributes. 
 
void PutOrientation(double *, double *, double *=NULL)
Put image x- and y-axis and z-axis. 
 
void WorldToImage(double &, double &) const
World to image coordinate conversion with two doubles. 
 
double _x
x coordinate of Point 
 
int Z() const
Get number of lattice points in z dimension. 
 
Array< Pair< string, string > > ParameterList
Ordered list of parameter name/value pairs. 
 
void Initialize(int, int=-1, double *=NULL)
Initialize matrix with number of rows and columns. 
 
Status
Enumeration of common states for entities such as objective function parameters. 
 
void ImageToWorld(double &, double &) const
Image to world coordinate conversion with two doubles. 
 
int T() const
Get number of lattice points in t dimension. 
 
int Y() const
Get number of lattice points in y dimension. 
 
double TimeToImage(double) const
Time to image coordinate conversion. 
 
double ImageToTime(double) const
Image to time coordinate conversion. 
 
void IndexToWorld(int, double &, double &) const
Get world coordinates (in mm) of pixl. 
 
double _zaxis[3]
Direction of z-axis. 
 
ExtrapolationMode
Image extrapolation modes. 
 
void Throw(ErrorType err, const char *func, Args... args) const
 
virtual const char * NameOfClass() const =0
Get name of class, which this object is an instance of. 
 
double TimeToLattice(double) const
Convert time to lattice coordinate. 
 
int X() const
Get number of lattice points in x dimension. 
 
double _z
z coordinate of Point 
 
MIRTKCU_API int iround(T x)
Round floating-point value and cast to int. 
 
void IndexToVoxel(int, int &, int &) const
Function to convert index to pixel coordinates. 
 
double _y
y coordinate of Point 
 
int Rows() const
Get number of rows. 
 
void GetOrientation(double *, double *, double *=NULL) const
Get image x- and y-axis and z-axis. 
 
MIRTK_Common_EXPORT const double inf
Positive infinity. 
 
double _yaxis[3]
Direction of y-axis.