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