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.