FreeFormTransformation3D.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2008-2015 Imperial College London
5  * Copyright 2008-2013 Daniel Rueckert, Julia Schnabel
6  * Copyright 2013-2015 Andreas Schuh
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef MIRTK_FreeFormTransformation3D_H
22 #define MIRTK_FreeFormTransformation3D_H
23 
24 #include "mirtk/FreeFormTransformation.h"
25 
26 #include "mirtk/ImageAttributes.h"
27 
28 
29 namespace mirtk {
30 
31 
32 /**
33  * Base class for 3D free-form transformations.
34  */
36 {
37  mirtkAbstractTransformationMacro(FreeFormTransformation3D);
38 
39  // ---------------------------------------------------------------------------
40  // Construction/Destruction
41 
42 public:
43 
44  // Import other overloads from base class
46 
47  /// Default attributes of free-form transformation lattice
48  static ImageAttributes DefaultAttributes(double, double, double,
49  double, double, double,
50  double, double, double,
51  const double *,
52  const double *,
53  const double *);
54 
55 protected:
56 
57  /// Default constructor
59 
60  /// Copy Constructor
62  CPInterpolator &, CPInterpolator * = NULL);
63 
64 public:
65 
66  /// Destructor
67  virtual ~FreeFormTransformation3D();
68 
69  // Import other Initialize overloades from base class
71 
72  /// Initialize free-form transformation
73  virtual void Initialize(const ImageAttributes &);
74 
75  // ---------------------------------------------------------------------------
76  // Derivatives
79 
80  /// Calculates the Jacobian of the transformation w.r.t a control point
81  virtual void JacobianDOFs(Matrix &, int, int, int, double, double, double) const;
82 
83  /// Calculates the Jacobian of the transformation w.r.t a control point
84  virtual void JacobianDOFs(Matrix &, int, double, double, double, double = 0, double = NaN) const;
85 
86  /// Calculates the Jacobian of the transformation w.r.t a control point
87  virtual void JacobianDOFs(double [3], int, int, int, double, double, double) const;
88 
89  /// Calculates the Jacobian of the transformation w.r.t a transformation parameter
90  virtual void JacobianDOFs(double [3], int, double, double, double, double = 0, double = NaN) const;
91 
92  /// Applies the chain rule to convert spatial non-parametric gradient
93  /// to a gradient w.r.t the parameters of this transformation
94  virtual void ParametricGradient(const GenericImage<double> *, double *,
95  const WorldCoordsImage *,
96  const WorldCoordsImage *,
97  double = NaN, double = 1) const;
98 
99  /// Applies the chain rule to convert point-wise non-parametric gradient
100  /// to a gradient w.r.t the parameters of this transformation.
101  virtual void ParametricGradient(const PointSet &, const Vector3D<double> *,
102  double *, double = 0, double = NaN, double = 1) const;
103 
104  // ---------------------------------------------------------------------------
105  // I/O
106 
107 protected:
108 
109  /// Reads transformation parameters from a file stream
111 
112  /// Writes transformation parameters to a file stream
113  virtual Cofstream &WriteDOFs(Cofstream &) const;
114 
115 public:
116 
117  // ---------------------------------------------------------------------------
118  // Deprecated
119 
120  /// \deprecated Use PutStatus instead.
121  void PutStatusCP(int, int, int, DOFStatus, DOFStatus, DOFStatus);
122 
123  /// \deprecated Use GetStatus instead.
124  void GetStatusCP(int, int, int, DOFStatus &, DOFStatus &, DOFStatus &) const;
125 
126  /// \deprecated Use overloaded BoundingBox method instead.
127  /// Note, however, that the new function swaps coordinates to
128  /// enforce p1[i] <= p2[i]. This is not done by this function.
129  void BoundingBoxCP(int cp, Point &, Point &, double = 1) const;
130 
131  /// \deprecated Use overloaded BoundingBox member function instead.
132  void BoundingBoxImage(const BaseImage *, int, int &, int &, int &,
133  int &, int &, int &, double = 1) const;
134 
135  /// \deprecated Use overloaded BoundingBox member function instead.
136  void MultiBoundingBoxImage(const BaseImage *,
137  int, int &, int &, int &,
138  int &, int &, int &, double = 1) const;
139 
140 };
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 // Inline definitions
144 ////////////////////////////////////////////////////////////////////////////////
145 
146 // =============================================================================
147 // Derivatives
148 // =============================================================================
149 
150 // -----------------------------------------------------------------------------
151 inline void FreeFormTransformation3D::JacobianDOFs(double jac[3], int, int, int, double, double, double) const
152 {
153  cerr << this->NameOfClass() << "::JacobianDOFs: Not implemented" << endl;
154  exit(1);
155 }
156 
157 // -----------------------------------------------------------------------------
158 inline void FreeFormTransformation3D::JacobianDOFs(double jac[3], int dof, double x, double y, double z, double, double) const
159 {
160  int ci, cj, ck;
161  this->IndexToLattice(dof / 3, ci, cj, ck);
162  this->JacobianDOFs(jac, ci, cj, ck, x, y, z);
163  const int c = dof % 3;
164  for (int i = 0; i < 3; ++i) {
165  if (i != c) jac[i] = .0;
166  }
167 }
168 
169 // -----------------------------------------------------------------------------
170 inline void FreeFormTransformation3D::JacobianDOFs(Matrix &jac, int ci, int cj, int ck, double x, double y, double z) const
171 {
172  double tmp[3];
173  this->JacobianDOFs(tmp, ci, cj, ck, x, y, z);
174  jac.Initialize(3, 3);
175  jac(0, 0) = tmp[0];
176  jac(1, 1) = tmp[1];
177  jac(2, 2) = tmp[2];
178 }
179 
180 // -----------------------------------------------------------------------------
181 inline void FreeFormTransformation3D::JacobianDOFs(Matrix &jac, int cp, double x, double y, double z, double, double) const
182 {
183  int ci, cj, ck;
184  this->IndexToLattice(cp, ci, cj, ck);
185  this->JacobianDOFs(jac, ci, cj, ck, x, y, z);
186 }
187 
188 // =============================================================================
189 // Deprecated
190 // =============================================================================
191 
192 // -----------------------------------------------------------------------------
193 inline void FreeFormTransformation3D::PutStatusCP(int i, int j, int k, DOFStatus sx, DOFStatus sy, DOFStatus sz)
194 {
195  PutStatus(i, j, k, sx, sy, sz);
196 }
197 
198 // -----------------------------------------------------------------------------
199 inline void FreeFormTransformation3D::GetStatusCP(int i, int j, int k, DOFStatus &sx, DOFStatus &sy, DOFStatus &sz) const
200 {
201  GetStatus(i, j, k, sx, sy, sz);
202 }
203 
204 // -----------------------------------------------------------------------------
205 inline void FreeFormTransformation3D::BoundingBoxCP(int cp, Point &p1, Point &p2, double fraction) const
206 {
207  int i, j, k;
208  IndexToLattice(cp, i, j, k);
209  p1 = Point(i - 2 * fraction, j - 2 * fraction, k - 2 * fraction);
210  p2 = Point(i + 2 * fraction, j + 2 * fraction, k + 2 * fraction);
211  this->LatticeToWorld(p1);
212  this->LatticeToWorld(p2);
213 }
214 
215 // -----------------------------------------------------------------------------
216 inline void
218 ::BoundingBoxImage(const BaseImage *image, int cp, int &i1, int &j1, int &k1,
219  int &i2, int &j2, int &k2, double fraction) const
220 {
221  // Calculate bounding box in world coordinates
222  Point p1, p2;
223  this->BoundingBoxCP(cp, p1, p2, fraction);
224 
225  // Transform world coordinates to image coordinates
226  image->WorldToImage(p1._x, p1._y, p1._z);
227  image->WorldToImage(p2._x, p2._y, p2._z);
228 
229  // Calculate bounding box in image coordinates
230  i1 = (p1._x < 0) ? 0 : int(p1._x)+1;
231  j1 = (p1._y < 0) ? 0 : int(p1._y)+1;
232  i2 = (int(p2._x) >= image->GetX()) ? image->GetX()-1 : int(p2._x);
233  j2 = (int(p2._y) >= image->GetY()) ? image->GetY()-1 : int(p2._y);
234 
235  if (image->GetZ() == 1) {
236  k1 = k2 = 0;
237  } else {
238  k1 = (p1._z < 0) ? 0 : int(p1._z)+1;
239  k2 = (int(p2._z) >= image->GetZ()) ? image->GetZ()-1 : int(p2._z);
240  }
241 }
242 
243 // -----------------------------------------------------------------------------
244 inline void
246 ::MultiBoundingBoxImage(const BaseImage *image, int cp, int &i1, int &j1, int &k1,
247  int &i2, int &j2, int &k2, double fraction) const
248 {
249  BoundingBoxImage(image, cp, i1, j1, k1, i2, j2, k2, 2.0 * fraction);
250 }
251 
252 
253 } // namespace mirtk
254 
255 #endif // MIRTK_FreeFormTransformation4D_H
void PutStatusCP(int, int, int, DOFStatus, DOFStatus, DOFStatus)
virtual void JacobianDOFs(Matrix &, int, double, double, double, double=0, double=NaN) const
Calculates the Jacobian of the transformation w.r.t the transformation parameters of a control point...
void MultiBoundingBoxImage(const BaseImage *, int, int &, int &, int &, int &, int &, int &, double=1) const
static ImageAttributes DefaultAttributes(const ImageAttributes &attr, double dx=-1.0, double dy=-1.0, double dz=-1.0, double dt=-1.0)
virtual void JacobianDOFs(Matrix &, int, int, int, double, double, double) const
Calculates the Jacobian of the transformation w.r.t a control point.
void WorldToImage(double &, double &) const
World to image coordinate conversion with two doubles.
Definition: BaseImage.h:1212
virtual Cifstream & ReadDOFs(Cifstream &, TransformationType)
Reads transformation parameters from a file stream.
void GetStatusCP(int, int, int, DOFStatus &, DOFStatus &, DOFStatus &) const
double _x
x coordinate of Point
Definition: Point.h:46
virtual ~FreeFormTransformation3D()
Destructor.
virtual void ParametricGradient(const GenericImage< double > *, double *, const WorldCoordsImage *, const WorldCoordsImage *, double=NaN, double=1) const
virtual void Initialize(const ImageAttributes &)=0
Initialize free-form transformation.
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.
Definition: Status.h:28
Definition: IOConfig.h:41
int GetX() const
Returns the number of voxels in the x-direction.
Definition: BaseImage.h:904
int GetY() const
Returns the number of voxels in the y-direction.
Definition: BaseImage.h:910
static ImageAttributes DefaultAttributes(double, double, double, double, double, double, double, double, double, const double *, const double *, const double *)
Default attributes of free-form transformation lattice.
void PutStatus(int, const CPStatus &)
Puts status of the parameters at a control point.
FreeFormTransformation3D(CPInterpolator &, CPInterpolator *=NULL)
Default constructor.
virtual void ParametricGradient(const GenericImage< double > *, double *, const WorldCoordsImage *, const WorldCoordsImage *, double=NaN, double=1) const
void BoundingBoxCP(int cp, Point &, Point &, double=1) const
void GetStatus(int, CPStatus &) const
Gets status of the parameters at a control point.
virtual const char * NameOfClass() const =0
Get name of class, which this object is an instance of.
void IndexToLattice(int, int &, int &) const
Get control point lattice coordinates from index.
void BoundingBoxImage(const BaseImage *, int, int &, int &, int &, int &, int &, int &, double=1) const
virtual void LatticeToWorld(double &, double &) const
Transforms lattice coordinates to world coordinates (in mm)
double _z
z coordinate of Point
Definition: Point.h:48
double _y
y coordinate of Point
Definition: Point.h:47
int GetZ() const
Returns the number of voxels in the z-direction.
Definition: BaseImage.h:916
virtual Cofstream & WriteDOFs(Cofstream &) const
Writes transformation parameters to a file stream.
virtual void Initialize(const ImageAttributes &)
Initialize free-form transformation.