File: itkRegistrationParameterScalesEstimator.h

package info (click to toggle)
insighttoolkit5 5.4.3-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 704,384 kB
  • sloc: cpp: 783,592; ansic: 628,724; xml: 44,704; fortran: 34,250; python: 22,874; sh: 4,078; pascal: 2,636; lisp: 2,158; makefile: 464; yacc: 328; asm: 205; perl: 203; lex: 146; tcl: 132; javascript: 98; csh: 81
file content (374 lines) | stat: -rw-r--r-- 13,552 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         https://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkRegistrationParameterScalesEstimator_h
#define itkRegistrationParameterScalesEstimator_h

#include "itkTransform.h"
#include "itkMatrixOffsetTransformBase.h"
#include "itkTranslationTransform.h"
#include "itkIdentityTransform.h"
#include "itkRigid3DPerspectiveTransform.h"

#include "itkOptimizerParameterScalesEstimator.h"
#include "itkImageRandomConstIteratorWithIndex.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "ITKOptimizersv4Export.h"

namespace itk
{
/** \class RegistrationParameterScalesEstimatorEnums
 * \brief This class contains all the enum classes used by RegistrationParameterScalesEstimator class.
 * \ingroup ITKOptimizersv4
 */
class RegistrationParameterScalesEstimatorEnums
{
public:
  /**
   * \class SamplingStrategy
   * \ingroup ITKOptimizersv4
   * The strategies to sample physical points in the virtual domain. */
  enum class SamplingStrategy : uint8_t
  {
    FullDomainSampling = 0,
    CornerSampling,
    RandomSampling,
    CentralRegionSampling,
    VirtualDomainPointSetSampling
  };
};
using SamplingStrategyEnum = RegistrationParameterScalesEstimatorEnums::SamplingStrategy;
// Define how to print enumeration
extern ITKOptimizersv4_EXPORT std::ostream &
                              operator<<(std::ostream & out, const RegistrationParameterScalesEstimatorEnums::SamplingStrategy value);

/**
 * \class RegistrationParameterScalesEstimator
 *  \brief Implements a registration helper class for estimating scales of
 * transform parameters and step sizes.
 *
 * Its input is a metric, from which the fixed/moving images and
 * transform objects are obtained.
 *
 * This class implements some common methods as building blocks called by
 * subclasses with various estimation strategies. One of these methods is
 * SampleVirtualDomain, which provides various choices of sampling the image
 * domain.
 *
 * \note When used with a PointSetToPointSet type metric, a VirtualDomainPointSet
 * must be defined, for use in shift estimation. See SetVirtualDomainPointSet().
 * The virtual domain point set can be retrieved from a metric using the
 * GetVirtualTransformedPointSet() method within the metric.
 *
 * \ingroup ITKOptimizersv4
 */
template <typename TMetric>
class ITK_TEMPLATE_EXPORT RegistrationParameterScalesEstimator
  : public OptimizerParameterScalesEstimatorTemplate<typename TMetric::ParametersValueType>
{
public:
  ITK_DISALLOW_COPY_AND_MOVE(RegistrationParameterScalesEstimator);

  /** Standard class type aliases. */
  using Self = RegistrationParameterScalesEstimator;
  using Superclass = OptimizerParameterScalesEstimatorTemplate<typename TMetric::ParametersValueType>;
  using Pointer = SmartPointer<Self>;
  using ConstPointer = SmartPointer<const Self>;

  /** \see LightObject::GetNameOfClass() */
  itkOverrideGetNameOfClassMacro(RegistrationParameterScalesEstimator);

  /** Type of scales */
  using typename Superclass::ScalesType;
  /** Type of parameters of the optimizer */
  using typename Superclass::ParametersType;
  /** Type of float */
  using typename Superclass::FloatType;

  using MetricType = TMetric;
  using MetricPointer = typename MetricType::Pointer;
  using MetricConstPointer = typename MetricType::ConstPointer;

  /** Type of the transform to initialize */
  using FixedTransformType = typename MetricType::FixedTransformType;
  using FixedTransformConstPointer = typename FixedTransformType::ConstPointer;

  using MovingTransformType = typename MetricType::MovingTransformType;
  using MovingTransformConstPointer = typename MovingTransformType::ConstPointer;

  /** dimension accessors */
  static constexpr SizeValueType FixedDimension = TMetric::FixedDimension;
  static constexpr SizeValueType MovingDimension = TMetric::MovingDimension;
  static constexpr SizeValueType VirtualDimension = TMetric::VirtualDimension;

  using VirtualImageType = typename TMetric::VirtualImageType;
  using VirtualImageConstPointer = typename TMetric::VirtualImageConstPointer;
  using VirtualImagePointer = typename TMetric::VirtualImagePointer;
  using VirtualSpacingType = typename TMetric::VirtualSpacingType;
  using VirtualRegionType = typename TMetric::VirtualRegionType;
  using VirtualSizeType = typename TMetric::VirtualSizeType;
  using VirtualPointType = typename TMetric::VirtualPointType;
  using VirtualIndexType = typename TMetric::VirtualIndexType;

  using VirtualPointSetType = typename TMetric::VirtualPointSetType;
  using VirtualPointSetPointer = typename TMetric::VirtualPointSetPointer;

  /** Enables backwards compatibility for enum values */
  using SamplingStrategyType = SamplingStrategyEnum;
#if !defined(ITK_LEGACY_REMOVE)
  // We need to expose the enum values at the class level
  // for backwards compatibility
  static constexpr SamplingStrategyType FullDomainSampling = SamplingStrategyType::FullDomainSampling;
  static constexpr SamplingStrategyType CornerSampling = SamplingStrategyType::CornerSampling;
  static constexpr SamplingStrategyType RandomSampling = SamplingStrategyType::RandomSampling;
  static constexpr SamplingStrategyType CentralRegionSampling = SamplingStrategyType::CentralRegionSampling;
  static constexpr SamplingStrategyType VirtualDomainPointSetSampling =
    SamplingStrategyType::VirtualDomainPointSetSampling;
#endif

  using SamplePointContainerType = std::vector<VirtualPointType>;

  /** Type of Jacobian of transform. */
  using JacobianType = typename TMetric::JacobianType;

  /** SetMetric sets the metric used in the estimation process.
   *  The transforms from the metric will be used for estimation, along
   *  with the images when appropriate.
   */
  itkSetObjectMacro(Metric, MetricType);
  itkGetConstObjectMacro(Metric, MetricType);

  /** m_TransformForward specifies which transform scales to be estimated.
   * m_TransformForward = true (default) for the moving transform parameters.
   * m_TransformForward = false for the fixed transform parameters.
   */
  itkSetMacro(TransformForward, bool);
  itkGetConstMacro(TransformForward, bool);
  itkBooleanMacro(TransformForward);

  /** Get/Set a point set for virtual domain sampling. */
#ifndef ITK_FUTURE_LEGACY_REMOVE
  virtual void
  SetVirtualDomainPointSet(VirtualPointSetType * const arg)
  {
    const auto * const constArg = arg;
    // Call the overload defined by itkSetConstObjectMacro, or an override.
    this->SetVirtualDomainPointSet(constArg);
  }
#endif
  itkSetConstObjectMacro(VirtualDomainPointSet, VirtualPointSetType);
  itkGetConstObjectMacro(VirtualDomainPointSet, VirtualPointSetType);

  /** the radius of the central region for sampling. */
  itkSetMacro(CentralRegionRadius, IndexValueType);
  itkGetConstMacro(CentralRegionRadius, IndexValueType);

  /** Estimate parameter scales */
  void
  EstimateScales(ScalesType & scales) override = 0;

  /** Estimate the step scale, the impact of a step on deformation. */
  FloatType
  EstimateStepScale(const ParametersType & step) override = 0;

  /** Estimate the scales of local steps. */
  void
  EstimateLocalStepScales(const ParametersType & step, ScalesType & localStepScales) override = 0;

  /** Estimate the trusted scale for steps. It returns the voxel spacing. */
  FloatType
  EstimateMaximumStepSize() override;

  /** Set the sampling strategy automatically for scales estimation. */
  virtual void
  SetScalesSamplingStrategy();

  /** Set the sampling strategy automatically for step scale estimation. */
  virtual void
  SetStepScaleSamplingStrategy();

protected:
  RegistrationParameterScalesEstimator();
  ~RegistrationParameterScalesEstimator() override = default;

  void
  PrintSelf(std::ostream & os, Indent indent) const override;

  /** Validate the metric and the transforms and set them. */
  bool
  CheckAndSetInputs();

  /** Set and get the number of samples. */
  itkSetMacro(NumberOfRandomSamples, SizeValueType);

  /** Set the sampling strategy. This is called from SetScalesSamplingStrategy() and
   *  SetStepScaleSamplingStrategy(). */
  itkSetMacro(SamplingStrategy, SamplingStrategyType);

  /**
   * Check if the transform is a general affine transform that maps a line
   * segment to a line segment.
   */
  bool
  CheckGeneralAffineTransform();

  /**
   * The templated version of CheckGeneralAffineTransform to check if the
   * transform is a general affine transform that maps a line segment to
   * a line segment.
   *
   * Examples are subclasses of MatrixOffsetTransformBaseType, TranslationTransform, Rigid3DPerspectiveTransform,
   * IdentityTransform, etc.
   */
  template <typename TTransform>
  bool
  CheckGeneralAffineTransformTemplated();

  /** Transform a physical point to a new physical point.
   *
   * We want to compute shift in physical space so that the scales is not sensitive to spacings and directions of
   * voxel sampling.
   */
  template <typename TTargetPointType>
  void
  TransformPoint(const VirtualPointType & point, TTargetPointType & mappedPoint);

  /** Transform a point to its continuous index. */
  template <typename TContinuousIndexType>
  void
  TransformPointToContinuousIndex(const VirtualPointType & point, TContinuousIndexType & mappedIndex);

  /** Compute the squared norms of the transform Jacobians w.r.t parameters at a physical point. */
  void
  ComputeSquaredJacobianNorms(const VirtualPointType & point, ParametersType & squareNorms);

  /** Check if the transform being optimized has local support. */
  bool
  TransformHasLocalSupportForScalesEstimation();

  /** Check if the transform being optimized is a displacement field transform. */
  bool
  IsDisplacementFieldTransform();

  /** Check if the transform being optimized is a B-spline transform. */
  bool
  IsBSplineTransform();

  /** Get the number of local parameters. */
  SizeValueType
  GetNumberOfLocalParameters();

  /** Update the transform with a change in parameters. */
  void
  UpdateTransformParameters(const ParametersType & deltaParameters);

  /** Sample the virtual domain with physical points and store the results in m_SamplePoints. */
  virtual void
  SampleVirtualDomain();

  /** Sample the virtual domain with all pixels. */
  void
  SampleVirtualDomainFully();

  /** Sample the virtual domain with corners.
   *
   * Sample the virtual domain with the points at image corners, and store the results in m_SamplePoints.
   */
  void
  SampleVirtualDomainWithCorners();

  /** Sample the virtual domain randomly in a uniform distribution. */
  void
  SampleVirtualDomainRandomly();

  /** Sample the virtual domain with the voxel in the central region.
   *
   * Samples the virtual domain with the voxels around the center.
   */
  void
  SampleVirtualDomainWithCentralRegion();

  /** Sample the virtual domain with all voxels inside a region. */
  void
  SampleVirtualDomainWithRegion(VirtualRegionType region);

  /** Sample the virtual domain with a point set */
  void
  SampleVirtualDomainWithPointSet();

  /** Get the central index of the virtual domain.
   *
   * Gets the region around the virtual image center.
   */
  VirtualIndexType
  GetVirtualDomainCentralIndex();

  /** Get the central region of the virtual domain. */
  VirtualRegionType
  GetVirtualDomainCentralRegion();

  /** Get the transform in use. */
  const TransformBaseTemplate<typename TMetric::MeasureType> *
  GetTransform();

  /** Get the dimension of the target transformed to. */
  SizeValueType
  GetDimension();

  /** Get the current sampling strategy. Note that this is changed
   * internally as the class is used for scale or step estimation. */
  itkGetMacro(SamplingStrategy, SamplingStrategyType);

  /** the metric object */
  MetricPointer m_Metric{};

  /** the samples in the virtual domain */
  SamplePointContainerType m_SamplePoints{};

  /** Keep track of the last sampling time. */
  mutable TimeStamp m_SamplingTime{};

  /**  the number of samples in the virtual domain */
  SizeValueType m_NumberOfRandomSamples{};

  /** the radius of the central region for sampling */
  IndexValueType m_CentralRegionRadius{};

  typename VirtualPointSetType::ConstPointer m_VirtualDomainPointSet{};

  // the threshold to decide if the number of random samples uses logarithm
  static constexpr SizeValueType SizeOfSmallDomain = 1000;

private:
  /** m_TransformForward specifies which transform scales to be estimated.
   * m_TransformForward = true (default) for the moving transform parameters.
   * m_TransformForward = false for the fixed transform parameters.
   */
  bool m_TransformForward{};

  // sampling strategy
  SamplingStrategyType m_SamplingStrategy{};

}; // class RegistrationParameterScalesEstimator
} // namespace itk


#ifndef ITK_MANUAL_INSTANTIATION
#  include "itkRegistrationParameterScalesEstimator.hxx"
#endif

#endif /* itkRegistrationParameterScalesEstimator_h */