go home Home | Main Page | Topics | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages
Loading...
Searching...
No Matches
itkAdvancedImageToImageMetric.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright UMC Utrecht and contributors
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkAdvancedImageToImageMetric_h
19#define itkAdvancedImageToImageMetric_h
20
21#include "itkImageToImageMetric.h"
22
23#include "itkImageSamplerBase.h"
24#include "itkGradientImageFilter.h"
25#include "itkBSplineInterpolateImageFunction.h"
29#include "itkFixedArray.h"
31
32#include "itkImageMaskSpatialObject.h"
33
34// Needed for checking for B-spline for faster implementation
37
38#include "elxDefaultConstruct.h"
39
40#include <cassert>
41#include <memory> // For unique_ptr.
42#include <typeinfo>
43
44namespace itk
45{
46
82
83template <typename TFixedImage, typename TMovingImage>
84class ITK_TEMPLATE_EXPORT AdvancedImageToImageMetric : public ImageToImageMetric<TFixedImage, TMovingImage>
85{
86public:
88
91 using Superclass = ImageToImageMetric<TFixedImage, TMovingImage>;
92 using Pointer = SmartPointer<Self>;
93 using ConstPointer = SmartPointer<const Self>;
97
99 itkStaticConstMacro(MovingImageDimension, unsigned int, TMovingImage::ImageDimension);
100 itkStaticConstMacro(FixedImageDimension, unsigned int, TFixedImage::ImageDimension);
101
103 using typename Superclass::CoordinateRepresentationType;
104 using typename Superclass::MovingImageType;
105 using typename Superclass::MovingImagePixelType;
106 using MovingImagePointer = typename MovingImageType::Pointer;
107 using typename Superclass::MovingImageConstPointer;
108 using typename Superclass::FixedImageType;
109 using FixedImagePointer = typename FixedImageType::Pointer;
110 using typename Superclass::FixedImageConstPointer;
111 using typename Superclass::FixedImageRegionType;
112 using typename Superclass::TransformType;
113 using typename Superclass::TransformPointer;
114 using typename Superclass::InputPointType;
115 using typename Superclass::OutputPointType;
116 using typename Superclass::TransformParametersType;
117 using typename Superclass::TransformJacobianType;
118 using typename Superclass::InterpolatorType;
119 using typename Superclass::InterpolatorPointer;
120 using typename Superclass::RealType;
121 using typename Superclass::GradientPixelType;
122 using typename Superclass::GradientImageType;
123 using typename Superclass::GradientImagePointer;
125 // Overrule the mask type from its base class, ITK ImageToImageMetric.
126 using FixedImageMaskType = ImageMaskSpatialObject<Self::FixedImageDimension>;
127 using FixedImageMaskPointer = SmartPointer<FixedImageMaskType>;
128 using FixedImageMaskConstPointer = SmartPointer<const FixedImageMaskType>;
129 using MovingImageMaskType = ImageMaskSpatialObject<Self::MovingImageDimension>;
130 using MovingImageMaskPointer = SmartPointer<MovingImageMaskType>;
131 using MovingImageMaskConstPointer = SmartPointer<const MovingImageMaskType>;
132
133 using typename Superclass::MeasureType;
134 using typename Superclass::DerivativeType;
135 using DerivativeValueType = typename DerivativeType::ValueType;
136 using typename Superclass::ParametersType;
137
139 using FixedImagePixelType = typename FixedImageType::PixelType;
140 using MovingImageRegionType = typename MovingImageType::RegionType;
141 using MovingImageDerivativeScalesType = FixedArray<double, Self::MovingImageDimension>;
142
148
152 using FixedImageLimiterOutputType = typename FixedImageLimiterType::OutputType;
155 using MovingImageLimiterOutputType = typename MovingImageLimiterType::OutputType;
156
158 using ScalarType = typename TransformType::ScalarType;
160 using NumberOfParametersType = typename AdvancedTransformType::NumberOfParametersType;
161
170
172 using ThreadInfoType = MultiThreaderBase::WorkUnitInfo;
173
175
176 virtual void
178 {
179 assert(arg == nullptr || typeid(*arg) == typeid(FixedImageMaskType));
180 Superclass::SetFixedImageMask(arg);
181 }
182
183 virtual void
185 {
186 assert(arg == nullptr || typeid(*arg) == typeid(MovingImageMaskType));
187 Superclass::SetMovingImageMask(arg);
188 }
189
190 const FixedImageMaskType *
191 GetFixedImageMask() const override
192 {
193 const auto * const mask = Superclass::GetFixedImageMask();
194 assert(mask == nullptr || typeid(*mask) == typeid(FixedImageMaskType));
195 return static_cast<const FixedImageMaskType *>(mask);
196 }
197
198 const MovingImageMaskType *
199 GetMovingImageMask() const override
200 {
201 const auto * const mask = Superclass::GetMovingImageMask();
202 assert(mask == nullptr || typeid(*mask) == typeid(MovingImageMaskType));
203 return static_cast<const MovingImageMaskType *>(mask);
204 }
205
207 virtual void
209 {
210 this->Superclass::SetTransform(arg);
211 if (m_AdvancedTransform != arg)
212 {
214 this->Modified();
215 }
216 }
217
218
220 AdvancedTransformType *
221 GetTransform() override
222 {
223 return m_AdvancedTransform.GetPointer();
224 }
225
227 const AdvancedTransformType *
228 GetTransform() const override
230 return m_AdvancedTransform.GetPointer();
231 }
235 itkSetObjectMacro(ImageSampler, ImageSamplerType);
239 return m_ImageSampler.GetPointer();
240 }
241
242
245 itkGetConstMacro(UseImageSampler, bool);
246
250 itkSetMacro(RequiredRatioOfValidSamples, double);
251 itkGetConstMacro(RequiredRatioOfValidSamples, double);
252
255 itkSetObjectMacro(MovingImageLimiter, MovingImageLimiterType);
256 itkGetConstObjectMacro(MovingImageLimiter, MovingImageLimiterType);
257 itkSetObjectMacro(FixedImageLimiter, FixedImageLimiterType);
258 itkGetConstObjectMacro(FixedImageLimiter, FixedImageLimiterType);
259
266 itkSetMacro(MovingLimitRangeRatio, double);
267 itkGetConstMacro(MovingLimitRangeRatio, double);
268 itkSetMacro(FixedLimitRangeRatio, double);
269 itkGetConstMacro(FixedLimitRangeRatio, double);
270
273 itkGetConstMacro(UseFixedImageLimiter, bool);
274 itkGetConstMacro(UseMovingImageLimiter, bool);
275
283 itkSetMacro(UseMovingImageDerivativeScales, bool);
284 itkGetConstMacro(UseMovingImageDerivativeScales, bool);
285
286 itkSetMacro(ScaleGradientWithRespectToMovingImageOrientation, bool);
287 itkGetConstMacro(ScaleGradientWithRespectToMovingImageOrientation, bool);
288
289 itkSetMacro(MovingImageDerivativeScales, MovingImageDerivativeScalesType);
290 itkGetConstReferenceMacro(MovingImageDerivativeScales, MovingImageDerivativeScalesType);
291
300 void
301 Initialize() override;
302
304 itkSetMacro(UseMetricSingleThreaded, bool);
305 itkGetConstReferenceMacro(UseMetricSingleThreaded, bool);
306 itkBooleanMacro(UseMetricSingleThreaded);
307
309 // \todo: maybe these can be united, check base class.
310 itkSetMacro(UseMultiThread, bool);
311 itkGetConstReferenceMacro(UseMultiThread, bool);
312 itkBooleanMacro(UseMultiThread);
313
319 virtual void
320 BeforeThreadedGetValueAndDerivative(const TransformParametersType & parameters) const;
321
322 void
323 SetRandomVariateGenerator(Statistics::MersenneTwisterRandomVariateGenerator & randomVariateGenerator)
324 {
325 m_RandomVariateGenerator = &randomVariateGenerator;
326 }
327
328protected:
331
333 ~AdvancedImageToImageMetric() override = default;
334
336 void
337 PrintSelf(std::ostream & os, Indent indent) const override;
338
340
342 using FixedImageIndexType = typename FixedImageType::IndexType;
343 using FixedImageIndexValueType = typename FixedImageIndexType::IndexValueType;
344 using MovingImageIndexType = typename MovingImageType::IndexType;
345 using FixedImagePointType = typename TransformType::InputPointType;
346 using MovingImagePointType = typename TransformType::OutputPointType;
347 using MovingImageContinuousIndexType = typename InterpolatorType::ContinuousIndexType;
348
351 BSplineInterpolateImageFunction<MovingImageType, CoordinateRepresentationType, double>;
352 using BSplineInterpolatorPointer = typename BSplineInterpolatorType::Pointer;
354 BSplineInterpolateImageFunction<MovingImageType, CoordinateRepresentationType, float>;
355 using BSplineInterpolatorFloatPointer = typename BSplineInterpolatorFloatType::Pointer;
361 using MovingImageDerivativeType = typename BSplineInterpolatorType::CovariantVectorType;
362
365
372
375
377 mutable bool m_TransformIsBSpline{ false };
378
388
390
392 virtual void
393 ThreadedGetValue(ThreadIdType) const
394 {}
395
397 virtual void
398 AfterThreadedGetValue(MeasureType &) const
399 {}
400
402 static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
404
406 void
408
410 virtual void
412 {}
413
415 virtual void
416 AfterThreadedGetValueAndDerivative(MeasureType &, DerivativeType &) const
417 {}
418
420 static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
422
424 void
426
428 static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
430
433 bool m_UseMultiThread{ false };
434
439 {
440 // To give the threads access to all members.
442 // Used for accumulating derivatives
445 };
446 mutable MultiThreaderParameterType m_ThreaderMetricParameters{};
447
456
457 // test per thread struct with padding and alignment
459 {
461 MeasureType st_Value;
462 DerivativeType st_Derivative;
463 };
464 itkPadStruct(ITK_CACHE_LINE_ALIGNMENT,
465 GetValueAndDerivativePerThreadStruct,
466 PaddedGetValueAndDerivativePerThreadStruct);
467 itkAlignedTypedef(ITK_CACHE_LINE_ALIGNMENT,
468 PaddedGetValueAndDerivativePerThreadStruct,
469 AlignedGetValueAndDerivativePerThreadStruct);
470 mutable std::unique_ptr<AlignedGetValueAndDerivativePerThreadStruct[]> m_GetValueAndDerivativePerThreadVariables{
471 nullptr
472 };
474
476 virtual void
478
480
482
484 virtual void
486
489 itkSetMacro(UseImageSampler, bool);
490
493 void
495
497
500 void
502
511 virtual bool
513 RealType & movingImageValue,
514 MovingImageDerivativeType * gradient) const
515 {
516 return EvaluateMovingImageValueAndDerivativeWithOptionalThreadId(mappedPoint, movingImageValue, gradient);
517 }
518
519 /* A faster version of `EvaluateMovingImageValueAndDerivative`: Non-virtual, using multithreading, and doing less
520 * dynamic memory allocation/decallocation operations, internally. */
521 bool
523 RealType & movingImageValue,
524 MovingImageDerivativeType * gradient,
525 const ThreadIdType threadId) const
526 {
527 return EvaluateMovingImageValueAndDerivativeWithOptionalThreadId(mappedPoint, movingImageValue, gradient, threadId);
528 }
529
534 virtual void
535 EvaluateTransformJacobianInnerProduct(const TransformJacobianType & jacobian,
536 const MovingImageDerivativeType & movingImageDerivative,
537 DerivativeType & imageJacobian) const;
538
540
545 void
547
549 void
551
554 TransformPoint(const FixedImagePointType & fixedImagePoint) const;
555
562 bool
564 TransformJacobianType & jacobian,
565 NonZeroJacobianIndicesType & nzji) const;
566
568 virtual bool
570
573 void
575
578 itkSetMacro(UseFixedImageLimiter, bool);
579 itkSetMacro(UseMovingImageLimiter, bool);
580
583
584 // Prevent accidentally calling SetFixedImageMask or SetMovingImageMask through the ITK ImageToImageMetric interface.
585 void
586 SetFixedImageMask(typename Superclass::FixedImageMaskType *) final
587 {
588 itkExceptionMacro("Intentionally left unimplemented!");
589 }
590
591 void
592 SetFixedImageMask(const typename Superclass::FixedImageMaskType *) final
593 {
594 itkExceptionMacro("Intentionally left unimplemented!");
595 }
596
597 void
598 SetMovingImageMask(typename Superclass::MovingImageMaskType *) final
599 {
600 itkExceptionMacro("Intentionally left unimplemented!");
601 }
602
603 void
604 SetMovingImageMask(const typename Superclass::MovingImageMaskType *) final
605 {
606 itkExceptionMacro("Intentionally left unimplemented!");
607 }
608
609 Statistics::MersenneTwisterRandomVariateGenerator &
614
615 // Note: Bypasses logical const-correctness
616 Statistics::MersenneTwisterRandomVariateGenerator &
621
622 // Protected using-declaration, to avoid `-Woverloaded-virtual` warnings from GCC (GCC 11.4) or clang (macos-12).
623 using Superclass::SetTransform;
624
625private:
626 template <typename... TOptionalThreadId>
627 bool
629 RealType & movingImageValue,
630 MovingImageDerivativeType * gradient,
631 const TOptionalThreadId... optionalThreadId) const;
632
640
642 bool m_UseImageSampler{ false };
648
649 MovingImageDerivativeScalesType m_MovingImageDerivativeScales{ MovingImageDerivativeScalesType::Filled(1.0) };
650
652 Statistics::MersenneTwisterRandomVariateGenerator * m_RandomVariateGenerator{ &m_DefaultRandomVariateGenerator };
653
654 // Private using-declarations, to avoid `-Woverloaded-virtual` warnings from GCC (GCC 11.4) or clang (macos-12).
655 using Superclass::TransformPoint;
656
658 {};
659
660 // Prevent accidentally accessing m_FixedImageMask or m_MovingImageMask directly from the ITK's ImageToImageMetric.
661 static constexpr DummyMask m_FixedImageMask{};
662 static constexpr DummyMask m_MovingImageMask{};
663};
664
665} // end namespace itk
666
667#ifndef ITK_MANUAL_INSTANTIATION
668# include "itkAdvancedImageToImageMetric.hxx"
669#endif
670
671#endif // end #ifndef itkAdvancedImageToImageMetric_h
Deformable transform using a B-spline representation.
This class combines two transforms: an 'initial transform' with a 'current transform'.
An extension of the ITK ImageToImageMetric. It is the intended base class for all elastix metrics.
itkStaticConstMacro(MovingImageDimension, unsigned int, TMovingImage::ImageDimension)
virtual void AfterThreadedGetValue(MeasureType &) const
virtual bool IsInsideMovingMask(const MovingImagePointType &point) const
virtual void ThreadedGetValueAndDerivative(ThreadIdType) const
const MovingImageMaskType * GetMovingImageMask() const override
typename BSplineOrder1TransformType::Pointer BSplineOrder1TransformPointer
typename TransformType::OutputPointType MovingImagePointType
typename ImageSamplerType::OutputVectorContainerPointer ImageSampleContainerPointer
void PrintSelf(std::ostream &os, Indent indent) const override
ITK_DISALLOW_COPY_AND_MOVE(AdvancedImageToImageMetric)
typename MovingImageType::RegionType MovingImageRegionType
typename AdvancedTransformType::NonZeroJacobianIndicesType NonZeroJacobianIndicesType
virtual bool EvaluateMovingImageValueAndDerivative(const MovingImagePointType &mappedPoint, RealType &movingImageValue, MovingImageDerivativeType *gradient) const
FixedArray< double, Self::MovingImageDimension > MovingImageDerivativeScalesType
typename FixedImageType::PixelType FixedImagePixelType
AdvancedLinearInterpolateImageFunction< MovingImageType, CoordinateRepresentationType > LinearInterpolatorType
BSplineInterpolateImageFunction< MovingImageType, CoordinateRepresentationType, float > BSplineInterpolatorFloatType
typename DerivativeType::ValueType DerivativeValueType
AdvancedBSplineDeformableTransform< ScalarType, FixedImageDimension, 3 > BSplineOrder3TransformType
typename FixedImageLimiterType::Pointer FixedImageLimiterPointer
virtual void InitializeImageSampler()
void SetFixedImageMask(const typename Superclass::FixedImageMaskType *) final
typename FixedImageIndexType::IndexValueType FixedImageIndexValueType
typename MovingImageType::IndexType MovingImageIndexType
virtual void SetTransform(AdvancedTransformType *arg)
void LaunchGetValueAndDerivativeThreaderCallback() const
Statistics::MersenneTwisterRandomVariateGenerator & GetRandomVariateGenerator()
typename ImageSamplerType::OutputVectorContainerType ImageSampleContainerType
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION GetValueAndDerivativeThreaderCallback(void *arg)
typename MovingImageType::Pointer MovingImagePointer
ImageMaskSpatialObject< Self::FixedImageDimension > FixedImageMaskType
bool FastEvaluateMovingImageValueAndDerivative(const MovingImagePointType &mappedPoint, RealType &movingImageValue, MovingImageDerivativeType *gradient, const ThreadIdType threadId) const
void SetFixedImageMask(typename Superclass::FixedImageMaskType *) final
typename BSplineOrder3TransformType::Pointer BSplineOrder3TransformPointer
void LaunchGetValueThreaderCallback() const
virtual void InitializeThreadingParameters() const
~AdvancedImageToImageMetric() override=default
typename FixedImageType::Pointer FixedImagePointer
typename ReducedBSplineInterpolatorType::Pointer ReducedBSplineInterpolatorPointer
virtual void BeforeThreadedGetValueAndDerivative(const TransformParametersType &parameters) const
typename BSplineOrder2TransformType::Pointer BSplineOrder2TransformPointer
void SetRandomVariateGenerator(Statistics::MersenneTwisterRandomVariateGenerator &randomVariateGenerator)
AdvancedTransform< ScalarType, FixedImageDimension, MovingImageDimension > AdvancedTransformType
typename FixedImageType::IndexType FixedImageIndexType
SmartPointer< MovingImageMaskType > MovingImageMaskPointer
virtual void ThreadedGetValue(ThreadIdType) const
Statistics::MersenneTwisterRandomVariateGenerator & GetMutableRandomVariateGenerator() const
elx::DefaultConstruct< Statistics::MersenneTwisterRandomVariateGenerator > m_DefaultRandomVariateGenerator
itkAlignedTypedef(ITK_CACHE_LINE_ALIGNMENT, PaddedGetValueAndDerivativePerThreadStruct, AlignedGetValueAndDerivativePerThreadStruct)
AdvancedBSplineDeformableTransform< ScalarType, FixedImageDimension, 1 > BSplineOrder1TransformType
LimiterFunctionBase< RealType, FixedImageDimension > FixedImageLimiterType
typename BSplineInterpolatorType::Pointer BSplineInterpolatorPointer
bool EvaluateMovingImageValueAndDerivativeWithOptionalThreadId(const MovingImagePointType &mappedPoint, RealType &movingImageValue, MovingImageDerivativeType *gradient, const TOptionalThreadId... optionalThreadId) const
ImageSamplerBase< FixedImageType > ImageSamplerType
MultiThreaderBase::WorkUnitInfo ThreadInfoType
typename BSplineInterpolatorType::CovariantVectorType MovingImageDerivativeType
virtual void AfterThreadedGetValueAndDerivative(MeasureType &, DerivativeType &) const
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION AccumulateDerivativesThreaderCallback(void *arg)
virtual void SetMovingImageMask(const MovingImageMaskType *const arg)
virtual void EvaluateTransformJacobianInnerProduct(const TransformJacobianType &jacobian, const MovingImageDerivativeType &movingImageDerivative, DerivativeType &imageJacobian) const
std::unique_ptr< AlignedGetValueAndDerivativePerThreadStruct[]> m_GetValueAndDerivativePerThreadVariables
LimiterFunctionBase< RealType, MovingImageDimension > MovingImageLimiterType
const FixedImageMaskType * GetFixedImageMask() const override
MovingImagePointType TransformPoint(const FixedImagePointType &fixedImagePoint) const
typename MovingImageLimiterType::OutputType MovingImageLimiterOutputType
typename TransformType::InputPointType FixedImagePointType
const AdvancedTransformType * GetTransform() const override
itkOverrideGetNameOfClassMacro(AdvancedImageToImageMetric)
void SetMovingImageMask(const typename Superclass::MovingImageMaskType *) final
typename FixedImageLimiterType::OutputType FixedImageLimiterOutputType
SmartPointer< FixedImageMaskType > FixedImageMaskPointer
itkStaticConstMacro(FixedImageDimension, unsigned int, TFixedImage::ImageDimension)
void SetMovingImageMask(typename Superclass::MovingImageMaskType *) final
typename BSplineInterpolatorFloatType::Pointer BSplineInterpolatorFloatPointer
BSplineInterpolateImageFunction< MovingImageType, CoordinateRepresentationType, double > BSplineInterpolatorType
AdvancedTransformType * GetTransform() override
ReducedDimensionBSplineInterpolateImageFunction< MovingImageType, CoordinateRepresentationType, double > ReducedBSplineInterpolatorType
typename TransformType::ScalarType ScalarType
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION GetValueThreaderCallback(void *arg)
virtual void SetFixedImageMask(const FixedImageMaskType *const arg)
SmartPointer< const FixedImageMaskType > FixedImageMaskConstPointer
Statistics::MersenneTwisterRandomVariateGenerator * m_RandomVariateGenerator
typename ImageSamplerType::Pointer ImageSamplerPointer
bool EvaluateTransformJacobian(const FixedImagePointType &fixedImagePoint, TransformJacobianType &jacobian, NonZeroJacobianIndicesType &nzji) const
typename InterpolatorType::ContinuousIndexType MovingImageContinuousIndexType
AdvancedCombinationTransform< ScalarType, FixedImageDimension > CombinationTransformType
typename AdvancedTransformType::NumberOfParametersType NumberOfParametersType
AdvancedBSplineDeformableTransform< ScalarType, FixedImageDimension, 2 > BSplineOrder2TransformType
SmartPointer< const MovingImageMaskType > MovingImageMaskConstPointer
typename MovingImageLimiterType::Pointer MovingImageLimiterPointer
itkPadStruct(ITK_CACHE_LINE_ALIGNMENT, GetValueAndDerivativePerThreadStruct, PaddedGetValueAndDerivativePerThreadStruct)
ImageMaskSpatialObject< Self::MovingImageDimension > MovingImageMaskType
typename LinearInterpolatorType::Pointer LinearInterpolatorPointer
Linearly interpolate an image at specified positions.
Transform maps points, vectors and covariant vectors from an input space to an output space.
This class is a base class for any image sampler.
typename OutputVectorContainerType::Pointer OutputVectorContainerPointer
VectorDataContainer< ImageSample< FixedImageType > > OutputVectorContainerType
MultiInputImageToImageMetricBase< TFixedImage, TMovingImage > Superclass
Base class for all ITK limiter function objects.
ImageMaskSpatialObject< Self::FixedImageDimension > FixedImageMaskType
Evaluates the B-Spline interpolation of an image. Spline order may be from 0 to 5.


Generated on 1774142652 for elastix by doxygen 1.15.0 elastix logo