1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
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 itkImageToImageMetric_h
19 #define itkImageToImageMetric_h
20 
21 #include "itkBSplineBaseTransform.h"
22 #include "itkBSplineInterpolateImageFunction.h"
23 #include "itkSingleValuedCostFunction.h"
24 #include "itkGradientRecursiveGaussianImageFilter.h"
25 #include "itkSpatialObject.h"
26 #include "itkCentralDifferenceImageFunction.h"
27 
28 namespace itk
29 {
30 /** \class ImageToImageMetric
31  * \brief Computes similarity between regions of two images.
32  *
33  * This Class is templated over the type of the two input images.
34  * It expects a Transform and an Interpolator to be plugged in.
35  * This particular class is the base class for a hierarchy of
36  * similarity metrics.
37  *
38  * This class computes a value that measures the similarity
39  * between the Fixed image and the transformed Moving image.
40  * The Interpolator is used to compute intensity values on
41  * non-grid positions resulting from mapping points through
42  * the Transform.
43  *
44  *
45  * \ingroup RegistrationMetrics
46  *
47  * \ingroup ITKRegistrationCommon
48  */
49 
50 template< typename TFixedImage,  typename TMovingImage >
51 class ITK_TEMPLATE_EXPORT ImageToImageMetric:
52   public SingleValuedCostFunction
53 {
54 public:
55   ITK_DISALLOW_COPY_AND_ASSIGN(ImageToImageMetric);
56 
57   /** Standard class type aliases. */
58   using Self = ImageToImageMetric;
59   using Superclass = SingleValuedCostFunction;
60   using Pointer = SmartPointer< Self >;
61   using ConstPointer = SmartPointer< const Self >;
62 
63   /** Type used for representing point components  */
64   using CoordinateRepresentationType = typename Superclass::ParametersValueType;
65 
66   /** Run-time type information (and related methods). */
67   itkTypeMacro(ImageToImageMetric, SingleValuedCostFunction);
68 
69   /**  Type of the moving Image. */
70   using MovingImageType = TMovingImage;
71   using MovingImagePixelType = typename TMovingImage::PixelType;
72   using MovingImageConstPointer = typename MovingImageType::ConstPointer;
73 
74   /**  Type of the fixed Image. */
75   using FixedImageType = TFixedImage;
76   using FixedImagePixelType = typename TFixedImage::PixelType;
77   using FixedImageConstPointer = typename FixedImageType::ConstPointer;
78   using FixedImageRegionType = typename FixedImageType::RegionType;
79 
80   /** Constants for the image dimensions */
81   static constexpr unsigned int MovingImageDimension = TMovingImage::ImageDimension;
82   static constexpr unsigned int FixedImageDimension = TFixedImage::ImageDimension;
83 
84   /**  Type of the Transform Base class */
85   using TransformType = Transform< CoordinateRepresentationType,
86                      Self::MovingImageDimension,
87                      Self::FixedImageDimension >;
88 
89   using TransformPointer = typename TransformType::Pointer;
90   using InputPointType = typename TransformType::InputPointType;
91   using OutputPointType = typename TransformType::OutputPointType;
92   using TransformParametersType = typename TransformType::ParametersType;
93   using TransformJacobianType = typename TransformType::JacobianType;
94 
95   /** Index and Point type alias support */
96   using FixedImageIndexType = typename FixedImageType::IndexType;
97   using FixedImageIndexValueType = typename FixedImageIndexType::IndexValueType;
98   using MovingImageIndexType = typename MovingImageType::IndexType;
99   using FixedImagePointType = typename TransformType::InputPointType;
100   using MovingImagePointType = typename TransformType::OutputPointType;
101 
102   using FixedImageIndexContainer = std::vector< FixedImageIndexType >;
103 
104   /**  Type of the Interpolator Base class */
105   using InterpolatorType = InterpolateImageFunction< MovingImageType, CoordinateRepresentationType >;
106 
107   /** Gaussian filter to compute the gradient of the Moving Image */
108   using RealType = typename NumericTraits< MovingImagePixelType >::RealType;
109   using GradientPixelType = CovariantVector< RealType, Self::MovingImageDimension >;
110   using GradientImageType = Image< GradientPixelType, Self::MovingImageDimension >;
111   using GradientImagePointer = SmartPointer< GradientImageType >;
112   using GradientImageFilterType = GradientRecursiveGaussianImageFilter< MovingImageType, GradientImageType >;
113   using GradientImageFilterPointer = typename GradientImageFilterType::Pointer;
114 
115   using InterpolatorPointer = typename InterpolatorType::Pointer;
116 
117   /**  Type for the mask of the fixed image. Only pixels that are "inside"
118        this mask will be considered for the computation of the metric */
119   using FixedImageMaskType = SpatialObject< Self::FixedImageDimension >;
120   using FixedImageMaskPointer = typename FixedImageMaskType::Pointer;
121   using FixedImageMaskConstPointer = typename FixedImageMaskType::ConstPointer;
122 
123   /**  Type for the mask of the moving image. Only pixels that are "inside"
124        this mask will be considered for the computation of the metric */
125   using MovingImageMaskType = SpatialObject< Self::MovingImageDimension >;
126   using MovingImageMaskPointer = typename MovingImageMaskType::Pointer;
127   using MovingImageMaskConstPointer = typename MovingImageMaskType::ConstPointer;
128 
129   /**  Type of the measure. */
130   using MeasureType = typename Superclass::MeasureType;
131 
132   /**  Type of the derivative. */
133   using DerivativeType = typename Superclass::DerivativeType;
134 
135   /**  Type of the parameters. */
136   using ParametersType = typename Superclass::ParametersType;
137 
138   /** Get/Set the Fixed Image.  */
139   itkSetConstObjectMacro( FixedImage, FixedImageType );
140   itkGetConstObjectMacro(FixedImage, FixedImageType );
141 
142   /** Get/Set the Moving Image.  */
143   itkSetConstObjectMacro( MovingImage, MovingImageType );
144   itkGetConstObjectMacro(MovingImage, MovingImageType );
145 
146   /** Connect the Transform. */
147   itkSetObjectMacro( Transform, TransformType );
148 
149   /** Get a pointer to the Transform.  */
150   itkGetModifiableObjectMacro(Transform, TransformType);
151 
152   /** Connect the Interpolator. */
153   itkSetObjectMacro(Interpolator, InterpolatorType);
154 
155   /** Get a pointer to the Interpolator.  */
156   itkGetModifiableObjectMacro(Interpolator, InterpolatorType);
157 
158   /** Get the number of pixels considered in the computation. */
GetNumberOfMovingImageSamples()159   SizeValueType GetNumberOfMovingImageSamples()
160   {
161     return this->GetNumberOfPixelsCounted();
162   }
163 
164   itkGetConstReferenceMacro(NumberOfPixelsCounted, SizeValueType);
165 
166   /** Set the region over which the metric will be computed */
167   virtual void SetFixedImageRegion(const FixedImageRegionType reg);
168 
169   /** Get the region over which the metric will be computed */
170   itkGetConstReferenceMacro(FixedImageRegion, FixedImageRegionType);
171 
172   /** Set/Get the moving image mask. */
173   itkSetObjectMacro(MovingImageMask, MovingImageMaskType);
174   itkSetConstObjectMacro(MovingImageMask, MovingImageMaskType);
175   itkGetConstObjectMacro(MovingImageMask, MovingImageMaskType);
176 
177   /** Set/Get the fixed image mask. */
178   itkSetObjectMacro(FixedImageMask, FixedImageMaskType);
179   itkSetConstObjectMacro(FixedImageMask, FixedImageMaskType);
180   itkGetConstObjectMacro(FixedImageMask, FixedImageMaskType);
181 
182   /** Set the fixed image indexes to be used as the samples when
183    *   computing the match metric */
184   void SetFixedImageIndexes(const FixedImageIndexContainer & indexes);
185 
186   void SetUseFixedImageIndexes(bool useIndex);
187 
188   itkGetConstReferenceMacro(UseFixedImageIndexes, bool);
189 
190   /** Set/Get number of work units to use for computations. */
191   void SetNumberOfWorkUnits(ThreadIdType numberOfThreads);
192   itkGetConstReferenceMacro(NumberOfWorkUnits, ThreadIdType);
193 
194   /** Set/Get gradient computation. */
195   itkSetMacro(ComputeGradient, bool);
196   itkGetConstReferenceMacro(ComputeGradient, bool);
197   itkBooleanMacro(ComputeGradient);
198 
199   /** Computes the gradient image and assigns it to m_GradientImage */
200   virtual void ComputeGradient();
201 
202   /** Get Gradient Image. */
203   itkGetModifiableObjectMacro(GradientImage, GradientImageType);
204 
205   /** Set the parameters defining the Transform. */
206   void SetTransformParameters(const ParametersType & parameters) const;
207 
208   /** Return the number of parameters required by the Transform */
GetNumberOfParameters()209   unsigned int GetNumberOfParameters() const override
210   {
211     return m_Transform->GetNumberOfParameters();
212   }
213 
214   /** Initialize the Metric by making sure that all the components
215    *  are present and plugged together correctly     */
216   virtual void Initialize();
217 
218   /** Initialize the components related to supporting multiple threads */
219   virtual void MultiThreadingInitialize();
220 
221   /** Number of spatial samples to used to compute metric
222    *   This sets the number of samples.  */
223   virtual void SetNumberOfFixedImageSamples(SizeValueType numSamples);
224   itkGetConstReferenceMacro(NumberOfFixedImageSamples, SizeValueType);
225 
226   /** Number of spatial samples to used to compute metric
227    *   This sets the number of samples.  */
SetNumberOfSpatialSamples(SizeValueType num)228   void SetNumberOfSpatialSamples(SizeValueType num)
229   {
230     this->SetNumberOfFixedImageSamples(num);
231   }
232 
GetNumberOfSpatialSamples()233   SizeValueType GetNumberOfSpatialSamples()
234   {
235     return this->GetNumberOfFixedImageSamples();
236   }
237 
238   /** Minimum fixed-image intensity needed for a sample to be used in the
239    *  metric computation */
240   void SetFixedImageSamplesIntensityThreshold(const FixedImagePixelType & thresh);
241 
242   itkGetConstReferenceMacro(FixedImageSamplesIntensityThreshold, FixedImagePixelType);
243 
244   void SetUseFixedImageSamplesIntensityThreshold(bool useThresh);
245 
246   itkGetConstReferenceMacro(UseFixedImageSamplesIntensityThreshold, bool);
247 
248   /** Select whether the metric will be computed using all the pixels on the
249    * fixed image region, or only using a set of randomly selected pixels.
250    * This value override IntensityThreshold, Masks, and SequentialSampling. */
251   void SetUseAllPixels(bool useAllPixels);
252 
UseAllPixelsOn()253   void UseAllPixelsOn()
254   {
255     this->SetUseAllPixels(true);
256   }
257 
UseAllPixelsOff()258   void UseAllPixelsOff()
259   {
260     this->SetUseAllPixels(false);
261   }
262 
263   itkGetConstReferenceMacro(UseAllPixels, bool);
264 
265   /** If set to true, then every pixel in the fixed image will be scanned to
266    * determine if it should be used in registration metric computation.  A
267    * pixel will be chosen if it meets any mask or threshold limits set.  If
268    * set to false, then UseAllPixels will be set to false. */
269   void SetUseSequentialSampling(bool sequentialSampling);
270 
271   itkGetConstReferenceMacro(UseSequentialSampling, bool);
272 
273   /** Reinitialize the seed of the random number generator that selects the
274    * sample of pixels used for estimating the image histograms and the joint
275    * histogram. By nature, this metric is not deterministic, since at each run
276    * it may select a different set of pixels. By initializing the random number
277    * generator seed to the same value you can restore determinism. On the other
278    * hand, calling the method ReinitializeSeed() without arguments will use the
279    * clock from your machine in order to have a very random initialization of
280    * the seed. This will indeed increase the non-deterministic behavior of the
281    * metric. */
282   void ReinitializeSeed();
283   void ReinitializeSeed(int seed);
284 
285   /** This boolean flag is only relevant when this metric is used along
286    * with a BSplineBaseTransform. The flag enables/disables the
287    * caching of values computed when a physical point is mapped through
288    * the BSplineBaseTransform. In particular it will cache the
289    * values of the BSpline weights for that points, and the indexes
290    * indicating what BSpline-grid nodes are relevant for that specific
291    * point. This caching is made optional due to the fact that the
292    * memory arrays used for the caching can reach large sizes even for
293    * moderate image size problems. For example, for a 3D image of
294    * 256^3, using 20% of pixels, these arrays will take about 1
295    * Gigabyte of RAM for storage. The ratio of computing time between
296    * using the cache or not using the cache can reach 1:5, meaning that
297    * using the caching can provide a five times speed up. It is
298    * therefore, interesting to enable the caching, if enough memory is
299    * available for it. The caching is enabled by default, in order to
300    * preserve backward compatibility with previous versions of ITK. */
301   itkSetMacro(UseCachingOfBSplineWeights, bool);
302   itkGetConstReferenceMacro(UseCachingOfBSplineWeights, bool);
303   itkBooleanMacro(UseCachingOfBSplineWeights);
304 
305   using MultiThreaderType = MultiThreaderBase;
306   /** Get the Threader. */
307   itkGetModifiableObjectMacro(Threader, MultiThreaderType);
GetThreaderTransform()308   const TransformPointer * GetThreaderTransform()
309   {
310     return m_ThreaderTransform;
311   }
312 
313 protected:
314   ImageToImageMetric();
315   ~ImageToImageMetric() override;
316 
317   void PrintSelf(std::ostream & os, Indent indent) const override;
318 
319   /** \class FixedImageSamplePoint
320    * A fixed image spatial sample consists of the fixed domain point
321    * and the fixed image value at that point.
322    * \ingroup ITKRegistrationCommon
323    */
324   class FixedImageSamplePoint
325   {
326 public:
FixedImageSamplePoint()327     FixedImageSamplePoint()
328     {
329       point.Fill(0.0);
330       value = 0;
331       valueIndex = 0;
332     }
333 
334     ~FixedImageSamplePoint() = default;
335 
336 public:
337     FixedImagePointType point;
338     double              value;
339     unsigned int        valueIndex;
340   };
341 
342   bool                     m_UseFixedImageIndexes{false};
343   FixedImageIndexContainer m_FixedImageIndexes;
344 
345   bool                m_UseFixedImageSamplesIntensityThreshold{false};
346   FixedImagePixelType m_FixedImageSamplesIntensityThreshold;
347 
348   /** FixedImageSamplePoint type alias support */
349   using FixedImageSampleContainer = std::vector< FixedImageSamplePoint >;
350 
351   /** Uniformly select a sample set from the fixed image domain. */
352   virtual void SampleFixedImageRegion(FixedImageSampleContainer & samples) const;
353 
354   virtual void SampleFixedImageIndexes(FixedImageSampleContainer & samples) const;
355 
356   /** Gather all the pixels from the fixed image domain. */
357   virtual void SampleFullFixedImageRegion(FixedImageSampleContainer &
358                                           samples) const;
359 
360   /** Container to store a set of points and fixed image values. */
361   FixedImageSampleContainer m_FixedImageSamples;
362 
363   SizeValueType          m_NumberOfParameters{0};
364 
365   SizeValueType m_NumberOfFixedImageSamples{50000};
366   //m_NumberOfPixelsCounted must be mutable because the const
367   //thread consolidation functions merge each work unit's values
368   //onto this accumulator variable.
369   mutable SizeValueType m_NumberOfPixelsCounted{0};
370 
371   FixedImageConstPointer  m_FixedImage;
372   MovingImageConstPointer m_MovingImage;
373 
374   /** Main transform to be used in thread = 0 */
375   TransformPointer m_Transform;
376   /** Copies of Transform helpers per thread (N-1 of them, since m_Transform
377    * will do the work for thread=0. */
378   TransformPointer *m_ThreaderTransform;
379 
380   InterpolatorPointer m_Interpolator;
381 
382   bool                 m_ComputeGradient{true};
383   GradientImagePointer m_GradientImage;
384 
385   FixedImageMaskConstPointer  m_FixedImageMask;
386   MovingImageMaskConstPointer m_MovingImageMask;
387 
388   ThreadIdType m_NumberOfWorkUnits{1};
389 
390   bool m_UseAllPixels{false};
391   bool m_UseSequentialSampling{false};
392 
393   bool m_ReseedIterator{false};
394 
395   mutable int m_RandomSeed;
396 
397   /** Types and variables related to BSpline deformable transforms.
398     * If the transform is of type third order BSplineBaseTransform,
399     * then we can speed up the metric derivative calculation by
400     * only inspecting the parameters within the support region
401     * of a mapped point.  */
402 
403   /** Boolean to indicate if the transform is BSpline deformable. */
404   bool m_TransformIsBSpline{false};
405 
406   /** The number of BSpline transform weights is the number of
407     * of parameter in the support region (per dimension ). */
408   SizeValueType m_NumBSplineWeights{0};
409 
410   static constexpr unsigned int DeformationSplineOrder = 3;
411 
412   using BSplineTransformType = BSplineBaseTransform< CoordinateRepresentationType,
413                                        FixedImageType ::ImageDimension,
414                                       Self::DeformationSplineOrder >;
415 
416   using BSplineTransformWeightsType = typename BSplineTransformType::WeightsType;
417   using WeightsValueType = typename BSplineTransformWeightsType::ValueType;
418   using BSplineTransformWeightsArrayType = Array2D< WeightsValueType >;
419 
420   using BSplineTransformIndexArrayType = typename BSplineTransformType::ParameterIndexArrayType;
421   using IndexValueType = typename BSplineTransformIndexArrayType::ValueType;
422   using BSplineTransformIndicesArrayType = Array2D< IndexValueType >;
423 
424   using MovingImagePointArrayType = std::vector< MovingImagePointType >;
425   using BooleanArrayType = std::vector< bool >;
426   using BSplineParametersOffsetType = FixedArray< SizeValueType,  FixedImageType ::ImageDimension >;
427   /**
428    * If a BSplineInterpolationFunction is used, this class obtain
429    * image derivatives from the BSpline interpolator. Otherwise,
430    * image derivatives are computed using central differencing.
431    */
432   using BSplineInterpolatorType = BSplineInterpolateImageFunction< MovingImageType,
433                                            CoordinateRepresentationType >;
434   /** Typedefs for using central difference calculator. */
435   using DerivativeFunctionType = CentralDifferenceImageFunction< MovingImageType,
436                                           CoordinateRepresentationType >;
437   using ImageDerivativesType =
438       CovariantVector< double, Self::MovingImageDimension >;
439 
440   typename BSplineTransformType::Pointer m_BSplineTransform;
441 
442   BSplineTransformWeightsArrayType m_BSplineTransformWeightsArray;
443   BSplineTransformIndicesArrayType m_BSplineTransformIndicesArray;
444   MovingImagePointArrayType        m_BSplinePreTransformPointsArray;
445   BooleanArrayType                 m_WithinBSplineSupportRegionArray;
446 
447   BSplineParametersOffsetType m_BSplineParametersOffset;
448 
449   // Variables needed for optionally caching values when using a BSpline
450   // transform.
451   bool                                   m_UseCachingOfBSplineWeights{true};
452   mutable BSplineTransformWeightsType    m_BSplineTransformWeights;
453   mutable BSplineTransformIndexArrayType m_BSplineTransformIndices;
454 
455   mutable BSplineTransformWeightsType    *m_ThreaderBSplineTransformWeights;
456   mutable BSplineTransformIndexArrayType *m_ThreaderBSplineTransformIndices;
457 
458   virtual void PreComputeTransformValues();
459 
460   /** Transform a point from FixedImage domain to MovingImage domain.
461    * This function also checks if mapped point is within support region. */
462   virtual void TransformPoint(unsigned int sampleNumber,
463                               MovingImagePointType & mappedPoint,
464                               bool & sampleWithinSupportRegion,
465                               double & movingImageValue,
466                               ThreadIdType threadId) const;
467 
468   virtual void TransformPointWithDerivatives(unsigned int sampleNumber,
469                                              MovingImagePointType & mappedPoint,
470                                              bool & sampleWithinSupportRegion,
471                                              double & movingImageValue,
472                                              ImageDerivativesType & gradient,
473                                              ThreadIdType threadId) const;
474 
475   /** Boolean to indicate if the interpolator BSpline. */
476   bool m_InterpolatorIsBSpline{false};
477   /** Pointer to BSplineInterpolator. */
478   typename BSplineInterpolatorType::Pointer m_BSplineInterpolator;
479 
480   /** Pointer to central difference calculator. */
481   typename DerivativeFunctionType::Pointer m_DerivativeCalculator;
482 
483   /** Compute image derivatives at a point. */
484   virtual void ComputeImageDerivatives(const MovingImagePointType & mappedPoint,
485                                        ImageDerivativesType & gradient,
486                                        ThreadIdType threadId) const;
487 
488   /**
489    * Types and variables related to multi-threading
490    */
491 
492   /**
493    * \class  ConstantPointerWrapper
494    * A class to wrap around a const pointer that can be passed
495    * as a non-const object to the SetSingleMethod function
496    * as a non-const void *.
497    * Do not allow inheritance for objects that are intended for static_cast<void *>
498    * \ingroup ITKRegistrationCommon
499    */
500   class ConstantPointerWrapper final
501   {
502   public:
ConstantPointerWrapper(ImageToImageMetric * i2i_metricPointer)503     ConstantPointerWrapper(ImageToImageMetric * i2i_metricPointer)
504     : m_ConstMetricPointer{ i2i_metricPointer }
505     {}
GetConstMetricPointer()506     const ImageToImageMetric * GetConstMetricPointer() const { return m_ConstMetricPointer; }
507   private:
508     const ImageToImageMetric * m_ConstMetricPointer;
509   };
510 
511   /**
512    * \class MultiThreaderWorkUnitInfoImageToImageMetricWrapper
513    * This helper local class is used to extract information from the
514    * MultiThreaderType::WorkUnitInfo info type
515    * Do not allow inheritance for objects that are intended for static_cast<void *>
516    * \ingroup ITKRegistrationCommon
517    */
518   class MultiThreaderWorkUnitInfoImageToImageMetricWrapper final
519   {
520   public:
MultiThreaderWorkUnitInfoImageToImageMetricWrapper(const void * workunitInfoAsVoid)521     MultiThreaderWorkUnitInfoImageToImageMetricWrapper(const void * workunitInfoAsVoid)
522       : m_WorkUnitInfo( static_cast<const typename MultiThreaderType::WorkUnitInfo *>( workunitInfoAsVoid ))
523     {  }
GetThreadId()524     ThreadIdType GetThreadId() const { return m_WorkUnitInfo->WorkUnitID; }
GetConstImageToImageMetricPointer()525     const ImageToImageMetric * GetConstImageToImageMetricPointer() const
526     {
527       return (static_cast<ConstantPointerWrapper *>( m_WorkUnitInfo ->UserData))->GetConstMetricPointer();
528     }
529   private:
530     const typename MultiThreaderType::WorkUnitInfo *m_WorkUnitInfo;
531   };
532 
533   MultiThreaderType::Pointer m_Threader;
534   ConstantPointerWrapper *   m_ConstSelfWrapper;
535   mutable unsigned int *     m_ThreaderNumberOfMovingImageSamples{nullptr};
536   bool                       m_WithinThreadPreProcess{false};
537   bool                       m_WithinThreadPostProcess{false};
538 
539   void                           GetValueMultiThreadedInitiate() const;
540 
541   void                           GetValueMultiThreadedPostProcessInitiate() const;
542 
543   static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION  GetValueMultiThreaded(void *arg);
544 
545   static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION  GetValueMultiThreadedPostProcess(void *arg);
546 
547   virtual inline void       GetValueThread(ThreadIdType threadId) const;
548 
GetValueThreadPreProcess(ThreadIdType itkNotUsed (threadId),bool itkNotUsed (withinSampleThread))549   virtual inline void       GetValueThreadPreProcess(
550     ThreadIdType itkNotUsed(threadId),
551     bool itkNotUsed(withinSampleThread) ) const
552   {}
GetValueThreadProcessSample(ThreadIdType itkNotUsed (threadId),SizeValueType itkNotUsed (fixedImageSample),const MovingImagePointType & itkNotUsed (mappedPoint),double itkNotUsed (movingImageValue))553   virtual inline bool       GetValueThreadProcessSample(
554     ThreadIdType itkNotUsed(threadId),
555     SizeValueType itkNotUsed(fixedImageSample),
556     const MovingImagePointType & itkNotUsed(mappedPoint),
557     double itkNotUsed(movingImageValue) ) const
558   { return false; }
GetValueThreadPostProcess(ThreadIdType itkNotUsed (threadId),bool itkNotUsed (withinSampleThread))559   virtual inline void       GetValueThreadPostProcess(
560     ThreadIdType itkNotUsed(threadId),
561     bool itkNotUsed(withinSampleThread) ) const
562   {}
563 
564   void                          GetValueAndDerivativeMultiThreadedInitiate() const;
565 
566   void                          GetValueAndDerivativeMultiThreadedPostProcessInitiate() const;
567 
568   static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION GetValueAndDerivativeMultiThreaded(void *arg);
569 
570   static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION GetValueAndDerivativeMultiThreadedPostProcess(void *arg);
571 
572   virtual inline void  GetValueAndDerivativeThread(ThreadIdType threadId) const;
573 
GetValueAndDerivativeThreadPreProcess(ThreadIdType itkNotUsed (threadId),bool itkNotUsed (withinSampleThread))574   virtual inline void  GetValueAndDerivativeThreadPreProcess(
575     ThreadIdType itkNotUsed(threadId),
576     bool itkNotUsed(withinSampleThread) ) const
577   {}
GetValueAndDerivativeThreadProcessSample(ThreadIdType itkNotUsed (threadId),SizeValueType itkNotUsed (fixedImageSample),const MovingImagePointType & itkNotUsed (mappedPoint),double itkNotUsed (movingImageValue),const ImageDerivativesType & itkNotUsed (movingImageGradientValue))578   virtual inline bool  GetValueAndDerivativeThreadProcessSample(
579     ThreadIdType itkNotUsed(threadId),
580     SizeValueType itkNotUsed(fixedImageSample),
581     const MovingImagePointType & itkNotUsed(mappedPoint),
582     double itkNotUsed(movingImageValue),
583     const ImageDerivativesType & itkNotUsed(movingImageGradientValue) ) const
584   { return false; }
GetValueAndDerivativeThreadPostProcess(ThreadIdType itkNotUsed (threadId),bool itkNotUsed (withinSampleThread))585   virtual inline void  GetValueAndDerivativeThreadPostProcess(
586     ThreadIdType itkNotUsed(threadId),
587     bool itkNotUsed(withinSampleThread) ) const
588   {}
589 
590   /** Synchronizes the threader transforms with the transform
591    *   member variable.
592    */
593   virtual void SynchronizeTransforms() const;
594 
595 private:
596   FixedImageRegionType m_FixedImageRegion;
597 };
598 } // end namespace itk
599 
600 #ifndef ITK_MANUAL_INSTANTIATION
601 #include "itkImageToImageMetric.hxx"
602 #endif
603 
604 #endif
605