00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkOptImageToImageMetric_h
00018 #define __itkOptImageToImageMetric_h
00019
00020 #include "itkSingleValuedCostFunction.h"
00021 #include "itkImageBase.h"
00022 #include "itkTransform.h"
00023 #include "itkInterpolateImageFunction.h"
00024 #include "itkSingleValuedCostFunction.h"
00025 #include "itkExceptionObject.h"
00026 #include "itkGradientRecursiveGaussianImageFilter.h"
00027 #include "itkSpatialObject.h"
00028 #include "itkBSplineDeformableTransform.h"
00029 #include "itkCentralDifferenceImageFunction.h"
00030 #include "itkCovariantVector.h"
00031
00032 #include "itkMultiThreader.h"
00033
00034 #include "itkOptBSplineInterpolateImageFunction.h"
00035
00036 namespace itk
00037 {
00038
00058 template <class TFixedImage, class TMovingImage>
00059 class ITK_EXPORT ImageToImageMetric
00060 : public SingleValuedCostFunction
00061 {
00062 public:
00064 typedef ImageToImageMetric Self;
00065 typedef SingleValuedCostFunction Superclass;
00066 typedef SmartPointer<Self> Pointer;
00067 typedef SmartPointer<const Self> ConstPointer;
00068
00070 typedef typename Superclass::ParametersValueType CoordinateRepresentationType;
00071
00073 itkTypeMacro(ImageToImageMetric, SingleValuedCostFunction);
00074
00076 typedef TMovingImage MovingImageType;
00077 typedef typename TMovingImage::PixelType MovingImagePixelType;
00078 typedef typename MovingImageType::ConstPointer MovingImageConstPointer;
00079
00081 typedef TFixedImage FixedImageType;
00082 typedef typename TFixedImage::PixelType FixedImagePixelType;
00083 typedef typename FixedImageType::ConstPointer FixedImageConstPointer;
00084 typedef typename FixedImageType::RegionType FixedImageRegionType;
00085
00087 itkStaticConstMacro(MovingImageDimension,
00088 unsigned int,
00089 TMovingImage::ImageDimension);
00090 itkStaticConstMacro(FixedImageDimension,
00091 unsigned int,
00092 TFixedImage::ImageDimension);
00094
00096 typedef Transform<CoordinateRepresentationType,
00097 itkGetStaticConstMacro(MovingImageDimension),
00098 itkGetStaticConstMacro(FixedImageDimension)>
00099 TransformType;
00100
00101 typedef typename TransformType::Pointer TransformPointer;
00102 typedef typename TransformType::InputPointType InputPointType;
00103 typedef typename TransformType::OutputPointType OutputPointType;
00104 typedef typename TransformType::ParametersType TransformParametersType;
00105 typedef typename TransformType::JacobianType TransformJacobianType;
00106
00108 typedef typename FixedImageType::IndexType FixedImageIndexType;
00109 typedef typename FixedImageIndexType::IndexValueType FixedImageIndexValueType;
00110 typedef typename MovingImageType::IndexType MovingImageIndexType;
00111 typedef typename TransformType::InputPointType FixedImagePointType;
00112 typedef typename TransformType::OutputPointType MovingImagePointType;
00113
00114 typedef std::vector<FixedImageIndexType> FixedImageIndexContainer;
00115
00117 typedef InterpolateImageFunction< MovingImageType,
00118 CoordinateRepresentationType >
00119 InterpolatorType;
00120
00122 typedef typename NumericTraits<MovingImagePixelType>::RealType
00123 RealType;
00124 typedef CovariantVector<RealType,
00125 itkGetStaticConstMacro(MovingImageDimension)>
00126 GradientPixelType;
00127 typedef Image<GradientPixelType,
00128 itkGetStaticConstMacro(MovingImageDimension)>
00129 GradientImageType;
00130 typedef SmartPointer<GradientImageType> GradientImagePointer;
00131 typedef GradientRecursiveGaussianImageFilter< MovingImageType,
00132 GradientImageType >
00133 GradientImageFilterType;
00134 typedef typename GradientImageFilterType::Pointer GradientImageFilterPointer;
00136
00137
00138 typedef typename InterpolatorType::Pointer InterpolatorPointer;
00139
00140
00143 typedef SpatialObject< itkGetStaticConstMacro(FixedImageDimension) >
00144 FixedImageMaskType;
00145 typedef typename FixedImageMaskType::Pointer FixedImageMaskPointer;
00146 typedef typename FixedImageMaskType::ConstPointer FixedImageMaskConstPointer;
00147
00150 typedef SpatialObject< itkGetStaticConstMacro(MovingImageDimension) >
00151 MovingImageMaskType;
00152 typedef typename MovingImageMaskType::Pointer MovingImageMaskPointer;
00153 typedef typename MovingImageMaskType::ConstPointer MovingImageMaskConstPointer;
00154
00155
00157 typedef typename Superclass::MeasureType MeasureType;
00158
00160 typedef typename Superclass::DerivativeType DerivativeType;
00161
00163 typedef typename Superclass::ParametersType ParametersType;
00164
00166 itkSetConstObjectMacro( FixedImage, FixedImageType );
00167
00169 itkGetConstObjectMacro( FixedImage, FixedImageType );
00170
00172 itkSetConstObjectMacro( MovingImage, MovingImageType );
00173
00175 itkGetConstObjectMacro( MovingImage, MovingImageType );
00176
00178 itkSetObjectMacro( Transform, TransformType );
00179
00181 itkGetConstObjectMacro( Transform, TransformType );
00182
00184 itkSetObjectMacro( Interpolator, InterpolatorType );
00185
00187 itkGetConstObjectMacro( Interpolator, InterpolatorType );
00188
00190 itkGetConstReferenceMacro( NumberOfMovingImageSamples, unsigned long );
00191 unsigned long GetNumberOfPixelsCounter( void )
00192 {
00193 return GetNumberOfMovingImageSamples();
00194 }
00196
00198 itkSetMacro( FixedImageRegion, FixedImageRegionType );
00199
00201 itkGetConstReferenceMacro( FixedImageRegion, FixedImageRegionType );
00202
00204 itkSetConstObjectMacro( MovingImageMask, MovingImageMaskType );
00205 itkGetConstObjectMacro( MovingImageMask, MovingImageMaskType );
00207
00209 itkSetConstObjectMacro( FixedImageMask, FixedImageMaskType );
00210 itkGetConstObjectMacro( FixedImageMask, FixedImageMaskType );
00212
00215 void SetFixedImageIndexes( const FixedImageIndexContainer & indexes );
00216
00218 itkSetMacro( NumberOfThreads, unsigned int );
00219 itkGetConstReferenceMacro( NumberOfThreads, unsigned int );
00221
00223 itkSetMacro( ComputeGradient, bool );
00224 itkGetConstReferenceMacro( ComputeGradient, bool );
00225 itkBooleanMacro(ComputeGradient );
00227
00229 virtual void ComputeGradient( void );
00230
00232 itkGetConstObjectMacro( GradientImage, GradientImageType );
00233
00235 void SetTransformParameters( const ParametersType & parameters ) const;
00236
00238 unsigned int GetNumberOfParameters( void ) const
00239 {
00240 return m_Transform->GetNumberOfParameters();
00241 }
00242
00245 virtual void Initialize( void ) throw ( ExceptionObject );
00246
00248 virtual void MultiThreadingInitialize( void ) throw ( ExceptionObject );
00249
00251 virtual void SetNumberOfFixedImageSamples( unsigned long numSamples )
00252 {
00253
00254 itkDebugMacro("Setting NumberOfFixedImageSamples to " << numSamples );
00255 if (this->m_NumberOfFixedImageSamples != numSamples)
00256 {
00257 if( this->m_NumberOfFixedImageSamples == 0 )
00258 {
00259
00260 this->m_NumberOfFixedImageSamples = 1;
00261 }
00262 this->m_UseAllPixels = false;
00263 this->m_NumberOfFixedImageSamples = numSamples;
00264 this->Modified();
00265 }
00266 }
00268
00269 itkGetConstReferenceMacro( NumberOfFixedImageSamples, unsigned long );
00270 void SetNumberOfSpatialSamples( unsigned long num )
00271 {
00272 this->SetNumberOfFixedImageSamples( num );
00273 }
00274 unsigned long GetNumberOfSpatialSamples( void )
00275 {
00276 return this->GetNumberOfFixedImageSamples();
00277 }
00278
00281 void SetFixedImageSamplesIntensityThreshold( const FixedImagePixelType & thresh );
00282 itkGetConstReferenceMacro( FixedImageSamplesIntensityThreshold, FixedImagePixelType );
00283 itkSetMacro( UseFixedImageSamplesIntensityThreshold, bool );
00284 itkGetConstReferenceMacro( UseFixedImageSamplesIntensityThreshold, bool );
00286
00289 itkSetMacro( UseAllPixels, bool );
00290 itkGetConstReferenceMacro( UseAllPixels, bool );
00291 itkBooleanMacro( UseAllPixels );
00293
00295 itkGetConstReferenceMacro( NumberOfPixelsCounted, unsigned long );
00296
00306 void ReinitializeSeed();
00307 void ReinitializeSeed( int seed );
00309
00326 itkSetMacro(UseCachingOfBSplineWeights,bool);
00327 itkGetConstReferenceMacro(UseCachingOfBSplineWeights,bool);
00328 itkBooleanMacro(UseCachingOfBSplineWeights);
00330
00331 protected:
00332 ImageToImageMetric();
00333 virtual ~ImageToImageMetric();
00334
00335 void PrintSelf(std::ostream& os, Indent indent) const;
00336
00337 mutable unsigned long m_NumberOfPixelsCounted;
00338
00342
00343 class FixedImageSamplePoint
00344 {
00345 public:
00346 FixedImageSamplePoint()
00347 {
00348 point.Fill(0.0);
00349 value = 0;
00350 valueIndex = 0;
00351 }
00352 ~FixedImageSamplePoint() {};
00353
00354 public:
00355 FixedImagePointType point;
00356 double value;
00357 unsigned int valueIndex;
00358 };
00360
00361 bool m_UseFixedImageIndexes;
00362 FixedImageIndexContainer m_FixedImageIndexes;
00363 FixedImagePixelType m_FixedImageSamplesIntensityThreshold;
00364 bool m_UseFixedImageSamplesIntensityThreshold;
00365
00367 typedef std::vector<FixedImageSamplePoint> FixedImageSampleContainer;
00368
00370 virtual void SampleFixedImageDomain( FixedImageSampleContainer & samples) const;
00371
00372 virtual void SampleFixedImageIndexes( FixedImageSampleContainer &
00373 samples);
00374
00376 virtual void SampleFullFixedImageDomain( FixedImageSampleContainer &
00377 samples);
00378
00380 FixedImageSampleContainer m_FixedImageSamples;
00381
00382 unsigned long m_NumberOfParameters;
00383 mutable ParametersType m_Parameters;
00384
00385 unsigned long m_NumberOfFixedImageSamples;
00386 mutable unsigned long m_NumberOfMovingImageSamples;
00387
00388 FixedImageConstPointer m_FixedImage;
00389 MovingImageConstPointer m_MovingImage;
00390
00392 TransformPointer m_Transform;
00393
00396 TransformPointer * m_ThreaderTransform;
00397
00398 InterpolatorPointer m_Interpolator;
00399
00400 bool m_ComputeGradient;
00401 GradientImagePointer m_GradientImage;
00402
00403 FixedImageMaskConstPointer m_FixedImageMask;
00404 MovingImageMaskConstPointer m_MovingImageMask;
00405
00406 unsigned int m_NumberOfThreads;
00407
00408 bool m_UseAllPixels;
00409
00410 bool m_ReseedIterator;
00411
00412 int m_RandomSeed;
00413
00421 bool m_TransformIsBSpline;
00422
00425 unsigned long m_NumBSplineWeights;
00426
00427 itkStaticConstMacro(DeformationSplineOrder, unsigned int, 3 );
00428
00429 typedef BSplineDeformableTransform< CoordinateRepresentationType,
00430 ::itk::GetImageDimension<FixedImageType>::ImageDimension,
00431 itkGetStaticConstMacro(DeformationSplineOrder) > BSplineTransformType;
00432
00433 typedef typename BSplineTransformType::WeightsType BSplineTransformWeightsType;
00434 typedef typename BSplineTransformWeightsType::ValueType WeightsValueType;
00435 typedef Array2D<WeightsValueType> BSplineTransformWeightsArrayType;
00436
00437 typedef typename BSplineTransformType::ParameterIndexArrayType
00438 BSplineTransformIndexArrayType;
00439 typedef typename BSplineTransformIndexArrayType::ValueType IndexValueType;
00440 typedef Array2D<IndexValueType> BSplineTransformIndicesArrayType;
00441
00442 typedef std::vector<MovingImagePointType> MovingImagePointArrayType;
00443 typedef std::vector<bool> BooleanArrayType;
00444 typedef FixedArray< unsigned long,
00445 ::itk::GetImageDimension<FixedImageType>
00446 ::ImageDimension > BSplineParametersOffsetType;
00452 typedef BSplineInterpolateImageFunction<MovingImageType,
00453 CoordinateRepresentationType>
00454 BSplineInterpolatorType;
00455
00457 typedef CentralDifferenceImageFunction<MovingImageType,
00458 CoordinateRepresentationType>
00459 DerivativeFunctionType;
00460 typedef CovariantVector< double,
00461 itkGetStaticConstMacro(MovingImageDimension) >
00462 ImageDerivativesType;
00463
00464
00465 typename BSplineTransformType::Pointer m_BSplineTransform;
00466
00467 BSplineTransformWeightsArrayType m_BSplineTransformWeightsArray;
00468 BSplineTransformIndicesArrayType m_BSplineTransformIndicesArray;
00469 MovingImagePointArrayType m_BSplinePreTransformPointsArray;
00470 BooleanArrayType m_WithinBSplineSupportRegionArray;
00471
00472 BSplineParametersOffsetType m_BSplineParametersOffset;
00473
00474
00475 bool m_UseCachingOfBSplineWeights;
00476 mutable BSplineTransformWeightsType m_BSplineTransformWeights;
00477 mutable BSplineTransformIndexArrayType m_BSplineTransformIndices;
00478
00479 mutable BSplineTransformWeightsType * m_ThreaderBSplineTransformWeights;
00480 mutable BSplineTransformIndexArrayType * m_ThreaderBSplineTransformIndices;
00481
00482 virtual void PreComputeTransformValues( void );
00483
00486 virtual void TransformPoint( unsigned int sampleNumber,
00487 MovingImagePointType& mappedPoint,
00488 bool& sampleWithinSupportRegion,
00489 double& movingImageValue,
00490 unsigned int threadID ) const;
00491
00492 virtual void TransformPointWithDerivatives( unsigned int sampleNumber,
00493 MovingImagePointType& mappedPoint,
00494 bool& sampleWithinSupportRegion,
00495 double& movingImageValue,
00496 ImageDerivativesType & gradient,
00497 unsigned int threadID ) const;
00498
00500 bool m_InterpolatorIsBSpline;
00501
00503 typename BSplineInterpolatorType::Pointer m_BSplineInterpolator;
00504
00506 typename DerivativeFunctionType::Pointer m_DerivativeCalculator;
00507
00509 virtual void ComputeImageDerivatives(
00510 const MovingImagePointType & mappedPoint,
00511 ImageDerivativesType & gradient,
00512 unsigned int threadID ) const;
00513
00514
00519 typedef MultiThreader MultiThreaderType;
00520
00521 struct MultiThreaderParameterType
00522 {
00523 ImageToImageMetric * metric;
00524 };
00525
00526 MultiThreaderType::Pointer m_Threader;
00527 MultiThreaderParameterType m_ThreaderParameter;
00528 mutable unsigned int m_ThreaderChunkSize;
00529 mutable unsigned int m_ThreaderSizeOfLastChunk;
00530 mutable unsigned int * m_ThreaderNumberOfMovingImageSamples;
00531 bool m_WithinThreadPreProcess;
00532 bool m_WithinThreadPostProcess;
00533
00534 void GetValueMultiThreadedPreProcessInitiate(
00535 void ) const;
00536 void GetValueMultiThreadedInitiate( void ) const;
00537 void GetValueMultiThreadedPostProcessInitiate(
00538 void ) const;
00539 static ITK_THREAD_RETURN_TYPE GetValueMultiThreadedPreProcess( void * arg );
00540 static ITK_THREAD_RETURN_TYPE GetValueMultiThreaded( void * arg );
00541 static ITK_THREAD_RETURN_TYPE GetValueMultiThreadedPostProcess( void * arg );
00542
00543 void GetValueThread( unsigned int threadID ) const;
00544 virtual inline void GetValueThreadPreProcess(
00545 unsigned int threadID,
00546 bool withinSampleThread ) const;
00547 virtual inline bool GetValueThreadProcessSample(
00548 unsigned int itkNotUsed(threadID),
00549 unsigned long itkNotUsed(fixedImageSample),
00550 const MovingImagePointType & itkNotUsed(mappedPoint),
00551 double itkNotUsed(movingImageValue)) const
00552 { return false; };
00553 virtual inline void GetValueThreadPostProcess(
00554 unsigned int itkNotUsed(threadID),
00555 bool itkNotUsed(withinSampleThread) ) const {};
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 void GetValueAndDerivativeMultiThreadedPreProcessInitiate(
00569 void) const;
00570 void GetValueAndDerivativeMultiThreadedInitiate( void) const;
00571 void GetValueAndDerivativeMultiThreadedPostProcessInitiate(
00572 void) const;
00573 static ITK_THREAD_RETURN_TYPE
00574 GetValueAndDerivativeMultiThreadedPreProcess(void * arg);
00575
00576 static ITK_THREAD_RETURN_TYPE
00577 GetValueAndDerivativeMultiThreaded(void * arg);
00578
00579 static ITK_THREAD_RETURN_TYPE
00580 GetValueAndDerivativeMultiThreadedPostProcess(void * arg);
00581
00582 void GetValueAndDerivativeThread(unsigned int threadID) const;
00583 virtual inline void GetValueAndDerivativeThreadPreProcess( unsigned int itkNotUsed(threadID),
00584 bool itkNotUsed(withinSampleThread)) const {};
00585 virtual inline bool GetValueAndDerivativeThreadProcessSample(
00586 unsigned int itkNotUsed(threadID),
00587 unsigned long itkNotUsed(fixedImageSample),
00588 const MovingImagePointType & itkNotUsed(mappedPoint),
00589 double itkNotUsed(movingImageValue),
00590 const ImageDerivativesType & itkNotUsed(movingImageGradientValue) ) const
00591 {
00592 return false;
00593 }
00594
00595 virtual inline void GetValueAndDerivativeThreadPostProcess(
00596 unsigned int itkNotUsed(threadID),
00597 bool itkNotUsed(withinSampleThread) ) const {};
00598
00602 void SynchronizeTransforms() const;
00603
00605 void NumberOfFixedImageSamplesUpdated();
00606
00607 private:
00608 ImageToImageMetric(const Self&);
00609 void operator=(const Self&);
00610
00611 FixedImageRegionType m_FixedImageRegion;
00612
00613 };
00614
00615 }
00616
00617 #ifndef ITK_MANUAL_INSTANTIATION
00618 #include "itkOptImageToImageMetric.txx"
00619 #endif
00620
00621 #endif
00622