EnergyMeasure.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2017 Imperial College London
5  * Copyright 2013-2017 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_EnergyMeasure_H
21 #define MIRTK_EnergyMeasure_H
22 
23 #include "mirtk/String.h"
24 
25 
26 namespace mirtk {
27 
28 
29 // -----------------------------------------------------------------------------
30 /// Enumeration of all available energy terms
32 {
33  EM_Unknown, ///< Unknown/invalid energy term
34  // Add new enumeration values below
35  // ---------------------------------------------------------------------------
36  // Image (dis-)similarity measures (cf. ImageSimilarity subclasses)
37  SIM_Begin,
38 
39  EM_JE, ///< Joint entropy
40  EM_CC, ///< Cross-correlation
41  EM_MI, ///< Mutual information
42  EM_NMI, ///< Normalized mutual information
43  EM_SSD, ///< Sum of squared differences
44  EM_CR_XY, ///< Correlation ratio
45  EM_CR_YX, ///< Correlation ratio
46  EM_LC, ///< Label consistency
47  EM_K, ///< Kappa statistic
48  EM_ML, ///< Maximum likelihood
49  EM_NGF_COS, ///< Cosine of normalzed gradient field
50  EM_NCC, ///< Normalized cross-correlation
51  EM_LNCC = EM_NCC, ///< Local normalized cross-correlation
52  EM_CoVar, ///< Covariance
53  EM_PSNR, ///< Peak signal-to-noise ratio
54 
55  SIM_End,
56  // ---------------------------------------------------------------------------
57  // Point set distance measures (cf. PointSetDistance subclasses)
58  PDM_Begin,
59 
60  EM_FRE, ///< Fiducial registration error (FRE) measure
61  EM_CorrespondenceDistance, ///< Point correspondence distance measure
62  EM_CurrentsDistance, ///< Distance measure based on currents representation
63  EM_VarifoldDistance, ///< Distance measure based on varifold representation
64 
65  PDM_End,
66  // ---------------------------------------------------------------------------
67  // External point set forces (cf. ExternalForce subclasses)
68  EFT_Begin,
69 
70  EM_BalloonForce, ///< Balloon/inflation force
71  EM_ImageEdgeForce, ///< Image edge force
72  EM_ImageEdgeDistance, ///< Image edge distance
73  EM_ImplicitSurfaceDistance, ///< Implicit surface distance force
74 
75  EFT_End,
76  // ---------------------------------------------------------------------------
77  // Internal point set forces (cf. InternalForce subclasses)
78  IFT_Begin,
79 
80  EM_MetricDistortion, ///< Minimize metric distortion
81  EM_Stretching, ///< Stretching force (rest edge length)
82  EM_Curvature, ///< Minimize curvature of point set surface
83  EM_QuadraticCurvature, ///< Quadratic fit of neighor to tangent plane distance
84  EM_GaussCurvature, ///< Gauss curvature constraint
85  EM_MeanCurvature, ///< Mean curvature constraint
86  EM_MaximumCurvature, ///< Maximum curvature constraint
87  EM_NonSelfIntersection, ///< Repels too close non-neighboring triangles
88  EM_RepulsiveForce, ///< Repels too close non-neighboring nodes
89  EM_InflationForce, ///< Inflate point set surface
90  EM_SpringForce, ///< Spring force
91  EM_NormalForce, ///< Constant force in normal direction
92 
93  IFT_End,
94  // ---------------------------------------------------------------------------
95  // Transformation regularization terms (cf. TransformationConstraint subclasses)
96  CM_Begin,
97 
98  EM_VolumePreservation, ///< Volume preservation constraint
99  EM_TopologyPreservation, ///< Topology preservation constraint
100  EM_Sparsity, ///< Default sparsity constraint
101  EM_BendingEnergy, ///< Thin-plate spline bending energy
102  EM_LinearElasticity, ///< Linear elastic energy
103  EM_L0Norm, ///< Sparsity constraint based on l0-norm
104  EM_L1Norm, ///< Sparsity constraint based on l1-norm
105  EM_L2Norm, ///< Sparsity constraint based on l2-norm
106  EM_SqLogDetJac, ///< Squared logarithm of the Jacobian determinant
107  EM_NegDetJac, ///< Penalise negative Jacobian determinant
108 
109  CM_End,
110 
111  // ---------------------------------------------------------------------------
112  // Others
113  EM_MeanSquaredDisplacementError, ///< Mean squared deviation from given deformation
114 
115  // ---------------------------------------------------------------------------
116  // Add new enumeration values above
117  EM_Last ///< Number of enumeration values + 1
118 };
119 
120 // -----------------------------------------------------------------------------
121 /// Convert energy measure enumeration value to string
122 template <>
123 inline string ToString(const EnergyMeasure &value, int w, char c, bool left)
124 {
125  const char *str;
126  switch (value) {
127  // ---------------------------------------------------------------------------
128  // Image (dis-)similarity measures
129  case EM_JE: str = "JE"; break;
130  case EM_CC: str = "CC"; break;
131  case EM_MI: str = "MI"; break;
132  case EM_NMI: str = "NMI"; break;
133  case EM_SSD: str = "SSD"; break;
134  case EM_CR_XY: str = "CR_XY"; break;
135  case EM_CR_YX: str = "CR_YX"; break;
136  case EM_LC: str = "LC"; break;
137  case EM_K: str = "K"; break;
138  case EM_ML: str = "ML"; break;
139  case EM_NGF_COS: str = "NGF_COS"; break;
140  case EM_NCC: str = "NCC"; break;
141  case EM_CoVar: str = "CoVar"; break;
142  case EM_PSNR: str = "PSNR"; break;
143 
144  // ---------------------------------------------------------------------------
145  // Point set distance measures
146  case EM_FRE: str = "FRE"; break;
147  case EM_CorrespondenceDistance: str = "PCD"; break;
148  case EM_CurrentsDistance: str = "CurrentsDistance"; break;
149  case EM_VarifoldDistance: str = "VarifoldDistance"; break;
150 
151  // ---------------------------------------------------------------------------
152  // External point set forces
153  case EM_BalloonForce: str = "BalloonForce"; break;
154  case EM_ImageEdgeForce: str = "ImageEdgeForce"; break;
155  case EM_ImageEdgeDistance: str = "ImageEdgeDistance"; break;
156  case EM_ImplicitSurfaceDistance: str = "ImplicitSurfaceDistance"; break;
157 
158  // ---------------------------------------------------------------------------
159  // Internal point set forces
160  case EM_MetricDistortion: str = "MetricDistortion"; break;
161  case EM_Stretching: str = "Stretching"; break;
162  case EM_Curvature: str = "Curvature"; break;
163  case EM_QuadraticCurvature: str = "QuadraticCurvature"; break;
164  case EM_GaussCurvature: str = "GaussCurvature"; break;
165  case EM_MeanCurvature: str = "MeanCurvature"; break;
166  case EM_MaximumCurvature : str = "MaximumCurvature"; break;
167  case EM_NonSelfIntersection: str = "NSI"; break;
168  case EM_RepulsiveForce: str = "Repulsion"; break;
169  case EM_InflationForce: str = "Inflation"; break;
170  case EM_SpringForce: str = "Spring"; break;
171  case EM_NormalForce: str = "NormalForce"; break;
172 
173  // -------------------------------------------------------------------------
174  // Transformation constraints
175  case EM_BendingEnergy: str = "BE"; break;
176  case EM_LinearElasticity: str = "LE"; break;
177  case EM_VolumePreservation: str = "VP"; break;
178  case EM_TopologyPreservation: str = "TP"; break;
179  case EM_Sparsity: str = "Sparsity"; break;
180  case EM_L0Norm: str = "L0"; break;
181  case EM_L1Norm: str = "L1"; break;
182  case EM_L2Norm: str = "L2"; break;
183  case EM_SqLogDetJac: str = "SqLogDetJac"; break;
184  case EM_NegDetJac: str = "NegDetJac"; break;
185 
186  // -------------------------------------------------------------------------
187  // Others
188  case EM_MeanSquaredDisplacementError: str = "MSDE"; break;
189 
190  // ---------------------------------------------------------------------------
191  // Unknown/invalid enumeration value
192  default: str = "Unknown";
193  }
194  return ToString(str, w, c, left);
195 }
196 
197 // -----------------------------------------------------------------------------
198 /// Convert energy measure enumeration value to human-friendly descriptive string
199 inline string ToPrettyString(const EnergyMeasure &value, int w = 0, char c = ' ', bool left = true)
200 {
201  const char *str;
202  switch (value) {
203  // ---------------------------------------------------------------------------
204  // Image (dis-)similarity measures
205  case EM_JE: str = "Joint entropy"; break;
206  case EM_CC: str = "Normalized cross-correlation"; break;
207  case EM_MI: str = "Mutual information"; break;
208  case EM_NMI: str = "Normalized mutual information"; break;
209  case EM_SSD: str = "Sum of squared differences"; break;
210  case EM_CR_XY: str = "Correlation ratio C(X|Y)"; break;
211  case EM_CR_YX: str = "Correlation ratio C(Y|X)"; break;
212  case EM_LC: str = "Label consistency"; break;
213  case EM_K: str = "Kappa statistic"; break;
214  case EM_ML: str = "Maximum likelihood"; break;
215  case EM_NGF_COS: str = "Cosine of normalized gradient field"; break;
216  case EM_NCC: str = "(Local) Normalized cross-correlation"; break;
217  case EM_CoVar: str = "Covariance"; break;
218  case EM_PSNR: str = "Peak signal-to-noise ratio"; break;
219 
220  // ---------------------------------------------------------------------------
221  // Point set distance measures
222  case EM_FRE: str = "Fiducial registration error"; break;
223  case EM_CorrespondenceDistance: str = "Point correspondence distance"; break;
224  case EM_CurrentsDistance: str = "Currents distance"; break;
225  case EM_VarifoldDistance: str = "Varifold distance"; break;
226 
227  // ---------------------------------------------------------------------------
228  // External point set forces
229  case EM_BalloonForce: str = "Balloon force"; break;
230  case EM_ImageEdgeForce: str = "Image edge force"; break;
231  case EM_ImageEdgeDistance: str = "Image edge distance"; break;
232  case EM_ImplicitSurfaceDistance: str = "Implicit surface distance"; break;
233 
234  // ---------------------------------------------------------------------------
235  // Internal point set forces
236  case EM_MetricDistortion: str = "Metric distortion"; break;
237  case EM_Stretching: str = "Stretching"; break;
238  case EM_Curvature: str = "Curvature"; break;
239  case EM_QuadraticCurvature: str = "Quadratic curvature"; break;
240  case EM_GaussCurvature: str = "Gauss curvature"; break;
241  case EM_MeanCurvature: str = "Mean curvature"; break;
242  case EM_MaximumCurvature: str = "Maximum curvature"; break;
243  case EM_NonSelfIntersection: str = "Non-self intersection"; break;
244  case EM_RepulsiveForce: str = "Repulsion"; break;
245  case EM_InflationForce: str = "Inflation"; break;
246  case EM_SpringForce: str = "Spring"; break;
247  case EM_NormalForce: str = "Normal"; break;
248 
249  // -------------------------------------------------------------------------
250  // Transformation constraints
251  case EM_BendingEnergy: str = "Bending energy"; break;
252  case EM_LinearElasticity: str = "Linear elasticity"; break;
253  case EM_VolumePreservation: str = "Volume preservation"; break;
254  case EM_TopologyPreservation: str = "Topology preservation"; break;
255  case EM_Sparsity: str = "Sparsity constraint"; break;
256  case EM_L0Norm: str = "l0 norm"; break;
257  case EM_L1Norm: str = "l1 norm"; break;
258  case EM_L2Norm: str = "l2 norm"; break;
259  case EM_SqLogDetJac: str = "Squared logarithm of Jacobian determinant"; break;
260  case EM_NegDetJac: str = "Negative Jacobian determinant penalty"; break;
261 
262  // -------------------------------------------------------------------------
263  // Others
264  case EM_MeanSquaredDisplacementError: str = "Mean squared displacement error"; break;
265 
266  // ---------------------------------------------------------------------------
267  // Unknown/invalid enumeration value
268  default: str = "Unknown energy term";
269  }
270  return ToString(str, w, c, left);
271 }
272 
273 // -----------------------------------------------------------------------------
274 /// Convert energy measure string to enumeration value
275 template <>
276 inline bool FromString(const char *str, EnergyMeasure &value)
277 {
278  const string lstr = ToLower(Trim(str));
279 
280  value = EM_Unknown;
281 
282  // ---------------------------------------------------------------------------
283  // Alternative names for image (dis-)similarity measures
284  if (value == EM_Unknown) {
285  if (lstr == "mse") value = EM_SSD;
286  else if (lstr == "meansquarederror") value = EM_SSD;
287  else if (lstr == "mean squared error") value = EM_SSD;
288  else if (lstr == "lcc") value = EM_NCC;
289  else if (lstr == "lncc") value = EM_NCC;
290  else if (lstr == "kappa") value = EM_K;
291  else if (lstr == "correlation ratio xy" ||
292  lstr == "correlationratioxy") value = EM_CR_XY;
293  else if (lstr == "correlation ratio" ||
294  lstr == "correlationratio" ||
295  lstr == "correlation ratio yx" ||
296  lstr == "correlationratioyx") value = EM_CR_YX;
297  }
298 
299  // ---------------------------------------------------------------------------
300  // Alternative names for point set distance measures
301  if (value == EM_Unknown) {
302  if (lstr == "fiducial error" || lstr == "fiducialerror" ||
303  lstr == "landmark error" || lstr == "landmarkerror" ||
304  lstr == "landmark registration error" || lstr == "landmarkregistrationerror") {
305  value = EM_FRE;
306  } else if (lstr == "correspondence distance" || lstr == "correspondencedistance") {
308  }
309  }
310 
311  // ---------------------------------------------------------------------------
312  // Alternative names for external point set forces
313  if (value == EM_Unknown) {
314  if (lstr == "edge force" || lstr == "edgeforce") value = EM_ImageEdgeForce;
315  if (lstr == "edge distance" || lstr == "edgedistance") value = EM_ImageEdgeDistance;
316  }
317 
318  // ---------------------------------------------------------------------------
319  // Alternative names for internal point set forces
320  if (value == EM_Unknown) {
321  if (strcmp(str, "EdgeLength") == 0) value = EM_Stretching;
322  else if (strcmp(str, "MetricDistortion") == 0) value = EM_MetricDistortion;
323  else if (strcmp(str, "Bending") == 0) value = EM_Curvature;
324  else if (strcmp(str, "SurfaceBending") == 0) value = EM_Curvature;
325  else if (strcmp(str, "SurfaceCurvature") == 0) value = EM_Curvature;
326  else if (strcmp(str, "GaussianCurvature") == 0) value = EM_GaussCurvature;
327  else if (strcmp(str, "RepulsiveForce") == 0) value = EM_RepulsiveForce;
328  else if (strcmp(str, "NonSelfIntersection") == 0) value = EM_NonSelfIntersection;
329  else if (strcmp(str, "InflationForce") == 0) value = EM_InflationForce;
330  else if (strcmp(str, "SurfaceInflation") == 0) value = EM_InflationForce;
331  }
332 
333  // ---------------------------------------------------------------------------
334  // Alternative names for transformation regularization terms
335  if (value == EM_Unknown) {
336  if (lstr == "jac") value = EM_SqLogDetJac;
337  else if (lstr == "logjac") value = EM_SqLogDetJac;
338  else if (lstr == "negjac") value = EM_NegDetJac;
339  else if (lstr == "elasticity") value = EM_LinearElasticity;
340  }
341 
342  // ---------------------------------------------------------------------------
343  // Convert default names of energy measures
344  // (cf. ToString(EnergyMeasure) and ToPrettyString(EnergyMeasure))
345  if (value == EM_Unknown) {
346  string pretty;
347  value = static_cast<EnergyMeasure>(EM_Last - 1);
348  while (value != EM_Unknown) {
349  if (lstr == ToLower(ToString(value))) break;
350  pretty = ToLower(ToPrettyString(value));
351  if (lstr == pretty || lstr == TrimAll(pretty, " -")) break;
352  value = static_cast<EnergyMeasure>(value - 1);
353  }
354  }
355 
356  return (value != EM_Unknown);
357 }
358 
359 
360 } // namespace mirtk
361 
362 
363 namespace std {
364 
365 /// Compute hash value from EnergyMeasure enumeration value
366 template<>
367 struct hash<mirtk::EnergyMeasure> {
368  size_t operator()(const mirtk::EnergyMeasure &enum_value) const {
369  return std::hash<int>()(enum_value);
370  }
371 };
372 
373 
374 } // namespace std
375 
376 
377 #endif // MIRTK_EnergyMeasure_H
string Trim(const string &str, const string &what=" \\)
Minimize metric distortion.
Definition: EnergyMeasure.h:80
Sparsity constraint based on l2-norm.
Local normalized cross-correlation.
Definition: EnergyMeasure.h:51
Default sparsity constraint.
Quadratic fit of neighor to tangent plane distance.
Definition: EnergyMeasure.h:83
Kappa statistic.
Definition: EnergyMeasure.h:47
Cosine of normalzed gradient field.
Definition: EnergyMeasure.h:49
Gauss curvature constraint.
Definition: EnergyMeasure.h:84
STL namespace.
string TrimAll(const string &str, const string &what=" \\)
Mean squared deviation from given deformation.
Distance measure based on currents representation.
Definition: EnergyMeasure.h:62
Balloon/inflation force.
Definition: EnergyMeasure.h:70
string ToPrettyString(const EnergyMeasure &value, int w=0, char c=' ', bool left=true)
Convert energy measure enumeration value to human-friendly descriptive string.
Correlation ratio.
Definition: EnergyMeasure.h:45
Implicit surface distance force.
Definition: EnergyMeasure.h:73
Repels too close non-neighboring triangles.
Definition: EnergyMeasure.h:87
Label consistency.
Definition: EnergyMeasure.h:46
Sparsity constraint based on l0-norm.
Inflate point set surface.
Definition: EnergyMeasure.h:89
string ToLower(const string &)
Convert string to lowercase letters.
Fiducial registration error (FRE) measure.
Definition: EnergyMeasure.h:60
Penalise negative Jacobian determinant.
Definition: IOConfig.h:41
Thin-plate spline bending energy.
Constant force in normal direction.
Definition: EnergyMeasure.h:91
Point correspondence distance measure.
Definition: EnergyMeasure.h:61
Minimize curvature of point set surface.
Definition: EnergyMeasure.h:82
Normalized cross-correlation.
Definition: EnergyMeasure.h:50
Image edge distance.
Definition: EnergyMeasure.h:72
Stretching force (rest edge length)
Definition: EnergyMeasure.h:81
Maximum curvature constraint.
Definition: EnergyMeasure.h:86
Covariance.
Definition: EnergyMeasure.h:52
Repels too close non-neighboring nodes.
Definition: EnergyMeasure.h:88
Squared logarithm of the Jacobian determinant.
Sum of squared differences.
Definition: EnergyMeasure.h:43
string ToString(const EnergyMeasure &value, int w, char c, bool left)
Convert energy measure enumeration value to string.
Normalized mutual information.
Definition: EnergyMeasure.h:42
bool FromString(const char *str, EnergyMeasure &value)
Convert energy measure string to enumeration value.
EnergyMeasure
Enumeration of all available energy terms.
Definition: EnergyMeasure.h:31
Mean curvature constraint.
Definition: EnergyMeasure.h:85
Cross-correlation.
Definition: EnergyMeasure.h:40
Unknown/invalid energy term.
Definition: EnergyMeasure.h:33
Sparsity constraint based on l1-norm.
Mutual information.
Definition: EnergyMeasure.h:41
Distance measure based on varifold representation.
Definition: EnergyMeasure.h:63
Image edge force.
Definition: EnergyMeasure.h:71
Volume preservation constraint.
Definition: EnergyMeasure.h:98
Linear elastic energy.
Maximum likelihood.
Definition: EnergyMeasure.h:48
Peak signal-to-noise ratio.
Definition: EnergyMeasure.h:53
Joint entropy.
Definition: EnergyMeasure.h:39
Spring force.
Definition: EnergyMeasure.h:90
Correlation ratio.
Definition: EnergyMeasure.h:44
Topology preservation constraint.
Definition: EnergyMeasure.h:99
Number of enumeration values + 1.