TransformationModel.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_TransformationModel_H
21 #define MIRTK_TransformationModel_H
22 
23 #include "mirtk/String.h"
24 #include "mirtk/Array.h"
25 #include "mirtk/ImageAttributes.h"
26 #include "mirtk/TransformationType.h"
27 
28 
29 namespace mirtk {
30 
31 
32 // -----------------------------------------------------------------------------
33 /// Enumeration of transformation models
34 ///
35 /// A transformation model is implemented by one or more transformation
36 /// classes and futhermore may be used to determine additional registration
37 /// settings, such as hard and soft transformation constraints. Thus, the
38 /// transformation model differs in semantics from the transformation type.
39 ///
40 /// \sa TransformationType, ToTransformationType
42 {
43  TM_Unknown, ///< Unknown/invalid transformation model
44  // Add new enumeration values below
45  TM_Rigid, ///< Linear transformation with up to 6 DoFs (rotate, translate)
46  TM_Similarity, ///< Linear transformation with up to 7 DoFs (rotate, translate, global scale)
47  TM_Affine, ///< Linear transformation with up to 12 DoFs (rotate, translate, scale, skew)
48  TM_LinearFFD, ///< Displacement field with linear interpolation
49  TM_BSplineFFD, ///< Displacement field with B-spline interpolation
50  TM_BSplineStatFFD, ///< Displacement field with B-spline interpolation using a statistical model
51  TM_BSplineSVFFD, ///< Stationary velocity field with B-spline interpolation
52  TM_BSplineTDFFD, ///< Non-stationary velocity field with B-spline interpolation
53  // Add new enumeration values above
54  TM_Last ///< Number of available transformation models + 1
55 };
56 
57 // -----------------------------------------------------------------------------
58 template <>
59 inline string ToString(const TransformationModel &m, int w, char c, bool left)
60 {
61  const char *str;
62  switch (m) {
63  case TM_Rigid: str = "Rigid"; break;
64  case TM_Similarity: str = "Similarity"; break;
65  case TM_Affine: str = "Affine"; break;
66  case TM_LinearFFD: str = "LinearFFD"; break;
67  case TM_BSplineFFD: str = "BSplineFFD"; break;
68  case TM_BSplineStatFFD: str = "BSplineStatFFD"; break;
69  case TM_BSplineSVFFD: str = "BSplineSVFFD"; break;
70  case TM_BSplineTDFFD: str = "BSplineTDFFD"; break;
71  default: str = "Unknown"; break;
72  }
73  return ToString(str, w, c, left);
74 }
75 
76 // -----------------------------------------------------------------------------
77 inline string ToPrettyString(const TransformationModel &m)
78 {
79  switch (m) {
80  case TM_Rigid: return "rigid transformation";
81  case TM_Similarity: return "similarity transformation";
82  case TM_Affine: return "affine transformation";
83  case TM_LinearFFD: return "non-parametric displacement field";
84  case TM_BSplineFFD: return "free-form deformation";
85  case TM_BSplineStatFFD: return "statistical free-form deformation";
86  case TM_BSplineSVFFD: return "parametric stationary velocity field transformation";
87  case TM_BSplineTDFFD: return "temporal diffeomorphic free-form deformation";
88  default: return "unknown transformation";
89  }
90 }
91 
92 // -----------------------------------------------------------------------------
93 template <>
94 inline bool FromString(const char *str, TransformationModel &m)
95 {
96  m = TM_Unknown;
97  // Alternative names of transformation models
98  if (strcmp(str, "FFD") == 0) m = TM_BSplineFFD;
99  else if (strcmp(str, "SVFFD") == 0) m = TM_BSplineSVFFD;
100  else if (strcmp(str, "TDFFD") == 0) m = TM_BSplineTDFFD;
101  // Default names of transformation models
102  if (m == TM_Unknown) {
103  m = static_cast<TransformationModel>(TM_Last - 1);
104  while (m != TM_Unknown) {
105  if (ToString(m) == str) break;
106  m = static_cast<TransformationModel>(m - 1);
107  }
108  }
109  return (m != TM_Unknown);
110 }
111 
112 // -----------------------------------------------------------------------------
113 /// Whether a given transformation model is linear
114 inline bool IsLinear(TransformationModel model)
115 {
116  return model == TM_Rigid || model == TM_Similarity || model == TM_Affine;
117 }
118 
119 // -----------------------------------------------------------------------------
120 /// Whether any given transformation model is linear
121 inline bool IsLinear(const Array<TransformationModel> &model)
122 {
123  for (size_t i = 0; i < model.size(); ++i) {
124  if (IsLinear(model[i])) return true;
125  }
126  return false;
127 }
128 
129 // -----------------------------------------------------------------------------
130 /// Whether any given transformation model is non-linear
131 inline bool IsNonLinear(const Array<TransformationModel> &model)
132 {
133  for (size_t i = 0; i < model.size(); ++i) {
134  if (!IsLinear(model[i])) return true;
135  }
136  return false;
137 }
138 
139 // -----------------------------------------------------------------------------
140 /// Whether a given transformation model is a FFD with a linear interpolation kernel
142 {
143  return model == TM_LinearFFD;
144 }
145 
146 // -----------------------------------------------------------------------------
147 /// Whether any given transformation model is a FFD with a linear interpolation kernel
148 inline bool IsLinearFFD(const Array<TransformationModel> &model)
149 {
150  for (size_t i = 0; i < model.size(); ++i) {
151  if (IsLinearFFD(model[i])) return true;
152  }
153  return false;
154 }
155 
156 // -----------------------------------------------------------------------------
157 /// Whether a given transformation model is diffeomorphic (velocity parameterization)
158 inline bool IsDiffeo(TransformationModel model)
159 {
160  return IsLinear(model) || model == TM_BSplineSVFFD || model == TM_BSplineTDFFD;
161 }
162 
163 // -----------------------------------------------------------------------------
164 /// Whether any given transformation model is a diffeomorphic model
165 inline bool IsDiffeo(const Array<TransformationModel> &model)
166 {
167  for (size_t i = 0; i < model.size(); ++i) {
168  if (IsDiffeo(model[i])) return true;
169  }
170  return false;
171 }
172 
173 // -----------------------------------------------------------------------------
174 /// Whether a given transformation model is 3D+t
176 {
177  return model == TM_BSplineTDFFD || model == TM_BSplineSVFFD;
178 }
179 
180 // -----------------------------------------------------------------------------
181 /// Whether any given transformation model is 3D+t
182 inline bool IsSpatioTemporal(const Array<TransformationModel> &model)
183 {
184  for (size_t i = 0; i < model.size(); ++i) {
185  if (IsSpatioTemporal(model[i])) return true;
186  }
187  return false;
188 }
189 
190 // -----------------------------------------------------------------------------
191 /// Get type of (default) transformation which implements a specific model
192 ///
193 /// The mapping from transformation model to transformtion type is not
194 /// one-to-one. More then one transformation can be suitable for a
195 /// transformation model. This function defines the default type used
196 /// for each model. The base registration filter implementations make use
197 /// of it, but a specialized registration filter can choose another
198 /// transformation for a given model if desired.
199 ///
200 /// For example, see ImageRegistrationFilter::TransformationType.
201 inline TransformationType
203  const ImageAttributes &domain)
204 {
205  // 2D/3D
206  if (domain._t == 1) {
207  switch (model) {
208  case TM_LinearFFD: return TRANSFORMATION_LINEAR_FFD_3D_v3;
209  case TM_BSplineFFD: return TRANSFORMATION_BSPLINE_FFD_3D_v3;
210  default: break;
211  }
212  // 4D
213  } else {
214  switch (model) {
215  case TM_LinearFFD: return TRANSFORMATION_LINEAR_FFD_4D_v2;
216  case TM_BSplineFFD: return TRANSFORMATION_BSPLINE_FFD_4D_v2;
217  default: break;
218  }
219  }
220  // nD
221  switch (model) {
222  case TM_Rigid: return TRANSFORMATION_RIGID;
223  case TM_Similarity: return TRANSFORMATION_SIMILARITY;
224  case TM_Affine: return TRANSFORMATION_AFFINE;
225  case TM_BSplineStatFFD: return TRANSFORMATION_BSPLINE_FFD_STATISTICAL;
226  case TM_BSplineSVFFD: return TRANSFORMATION_BSPLINE_FFD_SV_v5;
227  case TM_BSplineTDFFD: return TRANSFORMATION_BSPLINE_FFD_TD_v3;
228  default: return TRANSFORMATION_UNKNOWN;
229  }
230 }
231 
232 // -----------------------------------------------------------------------------
233 /// Enumeration of available multi-level transformation modes
235 {
236  MFFD_Default, ///< Choose suitable default multi-level transformation model
237  MFFD_None, ///< Use single transformation without additional global or local transformations
238  MFFD_Sum, ///< One transformation for each resolution level with additive composition
239  MFFD_Fluid, ///< One transformation for each resolution level with fluid composition
240  MFFD_LogSum ///< Additive multi-level stationary velocity field
241 };
242 
243 // -----------------------------------------------------------------------------
244 template <>
245 inline string ToString(const MFFDMode &m, int w, char c, bool left)
246 {
247  const char *str;
248  switch (m) {
249  case MFFD_Default: str = "Default"; break;
250  case MFFD_None: str = "None"; break;
251  case MFFD_Sum: str = "Sum"; break;
252  case MFFD_LogSum: str = "LogSum"; break;
253  case MFFD_Fluid: str = "Fluid"; break;
254  default: str = "Unknown"; break;
255  }
256  return ToString(str, w, c, left);
257 }
258 
259 // -----------------------------------------------------------------------------
260 template <>
261 inline bool FromString(const char *str, MFFDMode &m)
262 {
263  if (strcmp(str, "Default") == 0) m = MFFD_Default;
264  else if (strcmp(str, "None") == 0) m = MFFD_None;
265  else if (strcmp(str, "Sum") == 0) m = MFFD_Sum;
266  else if (strcmp(str, "LogSum") == 0) m = MFFD_LogSum;
267  else if (strcmp(str, "Fluid") == 0) m = MFFD_Fluid;
268  else return false;
269  return true;
270 }
271 
272 
273 } // namespace mirtk
274 
275 #endif // MIRTK_RegistrationFilter_H
Additive multi-level stationary velocity field.
Stationary velocity field with B-spline interpolation.
Number of available transformation models + 1.
bool IsLinear(TransformationModel model)
Whether a given transformation model is linear.
MFFDMode
Enumeration of available multi-level transformation modes.
Displacement field with B-spline interpolation using a statistical model.
string ToPrettyString(const EnergyMeasure &value, int w=0, char c=' ', bool left=true)
Convert energy measure enumeration value to human-friendly descriptive string.
Linear transformation with up to 6 DoFs (rotate, translate)
bool IsDiffeo(TransformationModel model)
Whether a given transformation model is diffeomorphic (velocity parameterization) ...
Definition: IOConfig.h:41
One transformation for each resolution level with fluid composition.
int _t
Image t-dimension (in voxels)
One transformation for each resolution level with additive composition.
Use single transformation without additional global or local transformations.
string ToString(const EnergyMeasure &value, int w, char c, bool left)
Convert energy measure enumeration value to string.
bool FromString(const char *str, EnergyMeasure &value)
Convert energy measure string to enumeration value.
bool IsLinearFFD(TransformationModel model)
Whether a given transformation model is a FFD with a linear interpolation kernel. ...
Non-stationary velocity field with B-spline interpolation.
Displacement field with B-spline interpolation.
Unknown/invalid transformation model.
Choose suitable default multi-level transformation model.
bool IsSpatioTemporal(TransformationModel model)
Whether a given transformation model is 3D+t.
Displacement field with linear interpolation.
TransformationType ToTransformationType(TransformationModel model, const ImageAttributes &domain)
Linear transformation with up to 12 DoFs (rotate, translate, scale, skew)
bool IsNonLinear(const Array< TransformationModel > &model)
Whether any given transformation model is non-linear.
Linear transformation with up to 7 DoFs (rotate, translate, global scale)