go home Home | Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages
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#include <vnl/vnl_sparse_matrix.h>
32
33#include "itkImageMaskSpatialObject.h"
34
35// Needed for checking for B-spline for faster implementation
38
39#include "itkPlatformMultiThreader.h"
40
41#include <memory> // For unique_ptr.
42
43namespace itk
44{
45
82template <class TFixedImage, class TMovingImage>
83class ITK_TEMPLATE_EXPORT AdvancedImageToImageMetric : public ImageToImageMetric<TFixedImage, TMovingImage>
84{
85public:
86 ITK_DISALLOW_COPY_AND_MOVE(AdvancedImageToImageMetric);
90 using Superclass = ImageToImageMetric<TFixedImage, TMovingImage>;
91 using Pointer = SmartPointer<Self>;
92 using ConstPointer = SmartPointer<const Self>;
95 itkTypeMacro(AdvancedImageToImageMetric, ImageToImageMetric);
98 itkStaticConstMacro(MovingImageDimension, unsigned int, TMovingImage::ImageDimension);
99 itkStaticConstMacro(FixedImageDimension, unsigned int, TFixedImage::ImageDimension);
102 using typename Superclass::CoordinateRepresentationType;
103 using typename Superclass::MovingImageType;
104 using typename Superclass::MovingImagePixelType;
105 using MovingImagePointer = typename MovingImageType::Pointer;
106 using typename Superclass::MovingImageConstPointer;
107 using typename Superclass::FixedImageType;
108 using FixedImagePointer = typename FixedImageType::Pointer;
109 using typename Superclass::FixedImageConstPointer;
110 using typename Superclass::FixedImageRegionType;
111 using typename Superclass::TransformType;
112 using typename Superclass::TransformPointer;
113 using typename Superclass::InputPointType;
114 using typename Superclass::OutputPointType;
115 using typename Superclass::TransformParametersType;
116 using typename Superclass::TransformJacobianType;
117 using typename Superclass::InterpolatorType;
118 using typename Superclass::InterpolatorPointer;
119 using typename Superclass::RealType;
120 using typename Superclass::GradientPixelType;
121 using typename Superclass::GradientImageType;
122 using typename Superclass::GradientImagePointer;
123 using typename Superclass::GradientImageFilterType;
124 using typename Superclass::GradientImageFilterPointer;
125 using typename Superclass::FixedImageMaskType;
126 using typename Superclass::FixedImageMaskPointer;
127 using typename Superclass::MovingImageMaskType;
128 using typename Superclass::MovingImageMaskPointer;
129 using typename Superclass::MeasureType;
130 using typename Superclass::DerivativeType;
131 using DerivativeValueType = typename DerivativeType::ValueType;
132 using typename Superclass::ParametersType;
134 using FixedImageMaskSpatialObject2Type = ImageMaskSpatialObject<Self::FixedImageDimension>;
135 using MovingImageMaskSpatialObject2Type = ImageMaskSpatialObject<Self::MovingImageDimension>;
138 using FixedImagePixelType = typename FixedImageType::PixelType;
139 using MovingImageRegionType = typename MovingImageType::RegionType;
140 using MovingImageDerivativeScalesType = FixedArray<double, Self::MovingImageDimension>;
151 using FixedImageLimiterOutputType = typename FixedImageLimiterType::OutputType;
154 using MovingImageLimiterOutputType = typename MovingImageLimiterType::OutputType;
157 using ScalarType = typename TransformType::ScalarType;
159 using NumberOfParametersType = typename AdvancedTransformType::NumberOfParametersType;
160
171 using HessianValueType = typename DerivativeType::ValueType;
172 using HessianType = vnl_sparse_matrix<HessianValueType>;
173
175 using ThreaderType = itk::PlatformMultiThreader;
176 using ThreadInfoType = typename ThreaderType::WorkUnitInfo;
181 virtual void
182 SetTransform(AdvancedTransformType * arg)
184 this->Superclass::SetTransform(arg);
185 if (this->m_AdvancedTransform != arg)
187 this->m_AdvancedTransform = arg;
188 this->Modified();
195 GetTransform() const override
196 {
197 return this->m_AdvancedTransform.GetPointer();
202 itkSetObjectMacro(ImageSampler, ImageSamplerType);
204 GetImageSampler() const
206 return this->m_ImageSampler.GetPointer();
212 itkGetConstMacro(UseImageSampler, bool);
213
217 itkSetMacro(RequiredRatioOfValidSamples, double);
218 itkGetConstMacro(RequiredRatioOfValidSamples, double);
219
222 itkSetObjectMacro(MovingImageLimiter, MovingImageLimiterType);
223 itkGetConstObjectMacro(MovingImageLimiter, MovingImageLimiterType);
224 itkSetObjectMacro(FixedImageLimiter, FixedImageLimiterType);
225 itkGetConstObjectMacro(FixedImageLimiter, FixedImageLimiterType);
226
233 itkSetMacro(MovingLimitRangeRatio, double);
234 itkGetConstMacro(MovingLimitRangeRatio, double);
235 itkSetMacro(FixedLimitRangeRatio, double);
236 itkGetConstMacro(FixedLimitRangeRatio, double);
240 itkGetConstMacro(UseFixedImageLimiter, bool);
241 itkGetConstMacro(UseMovingImageLimiter, bool);
250 itkSetMacro(UseMovingImageDerivativeScales, bool);
251 itkGetConstMacro(UseMovingImageDerivativeScales, bool);
252
253 itkSetMacro(ScaleGradientWithRespectToMovingImageOrientation, bool);
254 itkGetConstMacro(ScaleGradientWithRespectToMovingImageOrientation, bool);
255
256 itkSetMacro(MovingImageDerivativeScales, MovingImageDerivativeScalesType);
257 itkGetConstReferenceMacro(MovingImageDerivativeScales, MovingImageDerivativeScalesType);
258
267 void
268 Initialize() override;
269
273 virtual void
274 GetSelfHessian(const TransformParametersType & parameters, HessianType & H) const;
275
277 virtual void
278 SetNumberOfWorkUnits(ThreadIdType numberOfThreads);
279
281 itkSetMacro(UseMetricSingleThreaded, bool);
282 itkGetConstReferenceMacro(UseMetricSingleThreaded, bool);
283 itkBooleanMacro(UseMetricSingleThreaded);
286 // \todo: maybe these can be united, check base class.
287 itkSetMacro(UseMultiThread, bool);
288 itkGetConstReferenceMacro(UseMultiThread, bool);
289 itkBooleanMacro(UseMultiThread);
290
296 virtual void
297 BeforeThreadedGetValueAndDerivative(const TransformParametersType & parameters) const;
298
299protected:
302
304 ~AdvancedImageToImageMetric() override = default;
305
307 void
308 PrintSelf(std::ostream & os, Indent indent) const override;
309
313 using FixedImageIndexType = typename FixedImageType::IndexType;
314 using FixedImageIndexValueType = typename FixedImageIndexType::IndexValueType;
315 using MovingImageIndexType = typename MovingImageType::IndexType;
316 using FixedImagePointType = typename TransformType::InputPointType;
317 using MovingImagePointType = typename TransformType::OutputPointType;
318 using MovingImageContinuousIndexType = typename InterpolatorType::ContinuousIndexType;
319
322 BSplineInterpolateImageFunction<MovingImageType, CoordinateRepresentationType, double>;
323 using BSplineInterpolatorPointer = typename BSplineInterpolatorType::Pointer;
325 BSplineInterpolateImageFunction<MovingImageType, CoordinateRepresentationType, float>;
326 using BSplineInterpolatorFloatPointer = typename BSplineInterpolatorFloatType::Pointer;
332 using MovingImageDerivativeType = typename BSplineInterpolatorType::CovariantVectorType;
333 using CentralDifferenceGradientFilterType = GradientImageFilter<MovingImageType, RealType, RealType>;
334 using CentralDifferenceGradientFilterPointer = typename CentralDifferenceGradientFilterType::Pointer;
335
338
344 mutable ImageSamplerPointer m_ImageSampler{ nullptr };
345
347 bool m_InterpolatorIsLinear{ false };
348 bool m_InterpolatorIsBSpline{ false };
349 bool m_InterpolatorIsBSplineFloat{ false };
350 bool m_InterpolatorIsReducedBSpline{ false };
351 LinearInterpolatorPointer m_LinearInterpolator{ nullptr };
352 BSplineInterpolatorPointer m_BSplineInterpolator{ nullptr };
353 BSplineInterpolatorFloatPointer m_BSplineInterpolatorFloat{ nullptr };
354 ReducedBSplineInterpolatorPointer m_ReducedBSplineInterpolator{ nullptr };
355
356 CentralDifferenceGradientFilterPointer m_CentralDifferenceGradientFilter{ nullptr };
359 bool m_TransformIsAdvanced{ false };
360 typename AdvancedTransformType::Pointer m_AdvancedTransform{ nullptr };
361 mutable bool m_TransformIsBSpline{ false };
362
364 FixedImageLimiterPointer m_FixedImageLimiter{ nullptr };
365 MovingImageLimiterPointer m_MovingImageLimiter{ nullptr };
366 FixedImagePixelType m_FixedImageTrueMin{ 0 };
367 FixedImagePixelType m_FixedImageTrueMax{ 1 };
368 MovingImagePixelType m_MovingImageTrueMin{ 0 };
369 MovingImagePixelType m_MovingImageTrueMax{ 1 };
370 FixedImageLimiterOutputType m_FixedImageMinLimit{ 0 };
371 FixedImageLimiterOutputType m_FixedImageMaxLimit{ 1 };
372 MovingImageLimiterOutputType m_MovingImageMinLimit{ 0 };
373 MovingImageLimiterOutputType m_MovingImageMaxLimit{ 1 };
374
378 virtual void
379 ThreadedGetValue(ThreadIdType threadID)
380 {}
381
383 virtual void
384 AfterThreadedGetValue(MeasureType & value) const
385 {}
386
388 static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
390
392 void
394
396 virtual void
397 ThreadedGetValueAndDerivative(ThreadIdType threadID)
398 {}
399
401 virtual void
402 AfterThreadedGetValueAndDerivative(MeasureType & value, DerivativeType & derivative) const
403 {}
404
406 static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
408
410 void
412
414 static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
416
418 bool m_UseMetricSingleThreaded{ true };
419 bool m_UseMultiThread{ false };
421
426 {
427 // To give the threads access to all members.
429 // Used for accumulating derivatives
432 };
434
444 // test per thread struct with padding and alignment
446 {
448 MeasureType st_Value;
449 };
450 itkPadStruct(ITK_CACHE_LINE_ALIGNMENT, GetValuePerThreadStruct, PaddedGetValuePerThreadStruct);
451 itkAlignedTypedef(ITK_CACHE_LINE_ALIGNMENT, PaddedGetValuePerThreadStruct, AlignedGetValuePerThreadStruct);
452 mutable std::unique_ptr<AlignedGetValuePerThreadStruct[]> m_GetValuePerThreadVariables{ nullptr };
453 mutable ThreadIdType m_GetValuePerThreadVariablesSize{ 0 };
454
455 // test per thread struct with padding and alignment
457 {
459 MeasureType st_Value;
460 DerivativeType st_Derivative;
461 };
462 itkPadStruct(ITK_CACHE_LINE_ALIGNMENT,
464 PaddedGetValueAndDerivativePerThreadStruct);
465 itkAlignedTypedef(ITK_CACHE_LINE_ALIGNMENT,
466 PaddedGetValueAndDerivativePerThreadStruct,
467 AlignedGetValueAndDerivativePerThreadStruct);
468 mutable std::unique_ptr<AlignedGetValueAndDerivativePerThreadStruct[]> m_GetValueAndDerivativePerThreadVariables{
469 nullptr
470 };
471 mutable ThreadIdType m_GetValueAndDerivativePerThreadVariablesSize{ 0 };
472
474 virtual void
476
482 virtual void
484
487 itkSetMacro(UseImageSampler, bool);
488
491 virtual void
492 CheckNumberOfSamples(unsigned long wanted, unsigned long found) const;
493
498 virtual void
500
509 virtual bool
511 RealType & movingImageValue,
512 MovingImageDerivativeType * gradient) const
513 {
514 return EvaluateMovingImageValueAndDerivativeWithOptionalThreadId(mappedPoint, movingImageValue, gradient);
515 }
516
517 /* A faster version of `EvaluateMovingImageValueAndDerivative`: Non-virtual, using multithreading, and doing less
518 * dynamic memory allocation/decallocation operations, internally. */
519 bool
521 RealType & movingImageValue,
522 MovingImageDerivativeType * gradient,
523 const ThreadIdType threadId) const
524 {
525 return EvaluateMovingImageValueAndDerivativeWithOptionalThreadId(mappedPoint, movingImageValue, gradient, threadId);
526 }
527
532 virtual void
533 EvaluateTransformJacobianInnerProduct(const TransformJacobianType & jacobian,
534 const MovingImageDerivativeType & movingImageDerivative,
535 DerivativeType & imageJacobian) const;
536
543 virtual void
545
547 virtual void
549
552 TransformPoint(const FixedImagePointType & fixedImagePoint) const;
553
560 virtual bool
562 TransformJacobianType & jacobian,
563 NonZeroJacobianIndicesType & nzji) const;
564
566 virtual bool
568
571 virtual void
573
576 itkSetMacro(UseFixedImageLimiter, bool);
577 itkSetMacro(UseMovingImageLimiter, bool);
578
579 double m_FixedLimitRangeRatio{ 0.01 };
580 double m_MovingLimitRangeRatio{ 0.01 };
581
582private:
583 template <typename... TOptionalThreadId>
584 bool
586 RealType & movingImageValue,
587 MovingImageDerivativeType * gradient,
588 const TOptionalThreadId... optionalThreadId) const;
589
591 bool m_UseImageSampler{ false };
592 bool m_UseFixedImageLimiter{ false };
593 bool m_UseMovingImageLimiter{ false };
594 double m_RequiredRatioOfValidSamples{ 0.25 };
595 bool m_UseMovingImageDerivativeScales{ false };
596 bool m_ScaleGradientWithRespectToMovingImageOrientation{ false };
597
598 MovingImageDerivativeScalesType m_MovingImageDerivativeScales{ MovingImageDerivativeScalesType::Filled(1.0) };
599};
600
601} // end namespace itk
602
603#ifndef ITK_MANUAL_INSTANTIATION
604# include "itkAdvancedImageToImageMetric.hxx"
605#endif
606
607#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.
virtual bool IsInsideMovingMask(const MovingImagePointType &point) const
typename BSplineOrder1TransformType::Pointer BSplineOrder1TransformPointer
typename TransformType::OutputPointType MovingImagePointType
void PrintSelf(std::ostream &os, Indent indent) const override
virtual bool EvaluateTransformJacobian(const FixedImagePointType &fixedImagePoint, TransformJacobianType &jacobian, NonZeroJacobianIndicesType &nzji) const
typename MovingImageType::RegionType MovingImageRegionType
typename AdvancedTransformType::NonZeroJacobianIndicesType NonZeroJacobianIndicesType
itkAlignedTypedef(ITK_CACHE_LINE_ALIGNMENT, PaddedGetValuePerThreadStruct, AlignedGetValuePerThreadStruct)
virtual bool EvaluateMovingImageValueAndDerivative(const MovingImagePointType &mappedPoint, RealType &movingImageValue, MovingImageDerivativeType *gradient) const
virtual void CheckForAdvancedTransform()
typename FixedImageType::PixelType FixedImagePixelType
typename DerivativeType::ValueType DerivativeValueType
virtual void AfterThreadedGetValue(MeasureType &value) const
typename DerivativeType::ValueType HessianValueType
typename FixedImageLimiterType::Pointer FixedImageLimiterPointer
GradientImageFilter< MovingImageType, RealType, RealType > CentralDifferenceGradientFilterType
virtual void CheckForBSplineTransform() const
virtual void InitializeImageSampler()
typename FixedImageIndexType::IndexValueType FixedImageIndexValueType
typename MovingImageType::IndexType MovingImageIndexType
void LaunchGetValueAndDerivativeThreaderCallback() const
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION GetValueAndDerivativeThreaderCallback(void *arg)
virtual void ThreadedGetValue(ThreadIdType threadID)
typename MovingImageType::Pointer MovingImagePointer
bool FastEvaluateMovingImageValueAndDerivative(const MovingImagePointType &mappedPoint, RealType &movingImageValue, MovingImageDerivativeType *gradient, const ThreadIdType threadId) const
typename BSplineOrder3TransformType::Pointer BSplineOrder3TransformPointer
void LaunchGetValueThreaderCallback() const
virtual void ThreadedGetValueAndDerivative(ThreadIdType threadID)
virtual void InitializeThreadingParameters() const
~AdvancedImageToImageMetric() override=default
BSplineInterpolateImageFunction< MovingImageType, CoordinateRepresentationType, double > BSplineInterpolatorType
typename FixedImageType::Pointer FixedImagePointer
virtual void CheckNumberOfSamples(unsigned long wanted, unsigned long found) const
typename ThreaderType::WorkUnitInfo ThreadInfoType
typename ReducedBSplineInterpolatorType::Pointer ReducedBSplineInterpolatorPointer
virtual void BeforeThreadedGetValueAndDerivative(const TransformParametersType &parameters) const
typename BSplineOrder2TransformType::Pointer BSplineOrder2TransformPointer
typename FixedImageType::IndexType FixedImageIndexType
itkAlignedTypedef(ITK_CACHE_LINE_ALIGNMENT, PaddedGetValueAndDerivativePerThreadStruct, AlignedGetValueAndDerivativePerThreadStruct)
typename BSplineInterpolatorType::Pointer BSplineInterpolatorPointer
bool EvaluateMovingImageValueAndDerivativeWithOptionalThreadId(const MovingImagePointType &mappedPoint, RealType &movingImageValue, MovingImageDerivativeType *gradient, const TOptionalThreadId... optionalThreadId) const
typename CentralDifferenceGradientFilterType::Pointer CentralDifferenceGradientFilterPointer
itkPadStruct(ITK_CACHE_LINE_ALIGNMENT, GetValuePerThreadStruct, PaddedGetValuePerThreadStruct)
typename BSplineInterpolatorType::CovariantVectorType MovingImageDerivativeType
virtual void AfterThreadedGetValueAndDerivative(MeasureType &value, DerivativeType &derivative) const
BSplineInterpolateImageFunction< MovingImageType, CoordinateRepresentationType, float > BSplineInterpolatorFloatType
ImageMaskSpatialObject< Self::FixedImageDimension > FixedImageMaskSpatialObject2Type
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION AccumulateDerivativesThreaderCallback(void *arg)
virtual void EvaluateTransformJacobianInnerProduct(const TransformJacobianType &jacobian, const MovingImageDerivativeType &movingImageDerivative, DerivativeType &imageJacobian) const
MovingImagePointType TransformPoint(const FixedImagePointType &fixedImagePoint) const
typename MovingImageLimiterType::OutputType MovingImageLimiterOutputType
typename TransformType::InputPointType FixedImagePointType
const AdvancedTransformType * GetTransform() const override
vnl_sparse_matrix< HessianValueType > HessianType
typename FixedImageLimiterType::OutputType FixedImageLimiterOutputType
ImageMaskSpatialObject< Self::MovingImageDimension > MovingImageMaskSpatialObject2Type
typename BSplineInterpolatorFloatType::Pointer BSplineInterpolatorFloatPointer
virtual void SetNumberOfWorkUnits(ThreadIdType numberOfThreads)
typename TransformType::ScalarType ScalarType
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION GetValueThreaderCallback(void *arg)
typename ImageSamplerType::Pointer ImageSamplerPointer
typename InterpolatorType::ContinuousIndexType MovingImageContinuousIndexType
typename AdvancedTransformType::NumberOfParametersType NumberOfParametersType
typename MovingImageLimiterType::Pointer MovingImageLimiterPointer
virtual void GetSelfHessian(const TransformParametersType &parameters, HessianType &H) const
itkPadStruct(ITK_CACHE_LINE_ALIGNMENT, GetValueAndDerivativePerThreadStruct, PaddedGetValueAndDerivativePerThreadStruct)
MultiThreaderParameterType m_ThreaderMetricParameters
virtual void CheckForBSplineInterpolator()
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.
SmartPointer< Self > Pointer
std::vector< unsigned long > NonZeroJacobianIndicesType
This class is a base class for any image sampler.
Base class for all ITK limiter function objects.
SmartPointer< Self > Pointer
Evaluates the B-Spline interpolation of an image. Spline order may be from 0 to 5.
TOutputVectorContainer OutputVectorContainerType
typename OutputVectorContainerType::Pointer OutputVectorContainerPointer


Generated on Wed 12 Apr 2023 for elastix by doxygen 1.9.6 elastix logo