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
00149 typedef SpatialObject< itkGetStaticConstMacro(MovingImageDimension) >
00150 MovingImageMaskType;
00151 typedef typename MovingImageMaskType::Pointer MovingImageMaskPointer;
00152
00153
00155 typedef typename Superclass::MeasureType MeasureType;
00156
00158 typedef typename Superclass::DerivativeType DerivativeType;
00159
00161 typedef typename Superclass::ParametersType ParametersType;
00162
00164 itkSetConstObjectMacro( FixedImage, FixedImageType );
00165
00167 itkGetConstObjectMacro( FixedImage, FixedImageType );
00168
00170 itkSetConstObjectMacro( MovingImage, MovingImageType );
00171
00173 itkGetConstObjectMacro( MovingImage, MovingImageType );
00174
00176 itkSetObjectMacro( Transform, TransformType );
00177
00179 itkGetConstObjectMacro( Transform, TransformType );
00180
00182 itkSetObjectMacro( Interpolator, InterpolatorType );
00183
00185 itkGetConstObjectMacro( Interpolator, InterpolatorType );
00186
00188 itkGetConstReferenceMacro( NumberOfMovingImageSamples, unsigned long );
00189 unsigned long GetNumberOfPixelsCounter( void )
00190 {
00191 return GetNumberOfMovingImageSamples();
00192 }
00194
00196 itkSetMacro( FixedImageRegion, FixedImageRegionType );
00197
00199 itkGetConstReferenceMacro( FixedImageRegion, FixedImageRegionType );
00200
00202 itkSetObjectMacro( MovingImageMask, MovingImageMaskType );
00203 itkGetConstObjectMacro( MovingImageMask, MovingImageMaskType );
00205
00207 itkSetObjectMacro( FixedImageMask, FixedImageMaskType );
00208 itkGetConstObjectMacro( FixedImageMask, FixedImageMaskType );
00210
00213 void SetFixedImageIndexes( const FixedImageIndexContainer & indexes );
00214
00216 itkSetMacro( NumberOfThreads, unsigned int );
00217 itkGetConstReferenceMacro( NumberOfThreads, unsigned int );
00219
00221 itkSetMacro( ComputeGradient, bool );
00222 itkGetConstReferenceMacro( ComputeGradient, bool );
00223 itkBooleanMacro(ComputeGradient );
00225
00227 virtual void ComputeGradient( void );
00228
00230 itkGetConstObjectMacro( GradientImage, GradientImageType );
00231
00233 void SetTransformParameters( const ParametersType & parameters ) const;
00234
00236 unsigned int GetNumberOfParameters( void ) const
00237 {
00238 return m_Transform->GetNumberOfParameters();
00239 }
00240
00243 virtual void Initialize( void ) throw ( ExceptionObject );
00244
00246 virtual void MultiThreadingInitialize( void ) throw ( ExceptionObject );
00247
00249 virtual void SetNumberOfFixedImageSamples( unsigned long numSamples )
00250 {
00251
00252 itkDebugMacro("Setting NumberOfFixedImageSamples to " << numSamples );
00253 if (this->m_NumberOfFixedImageSamples != numSamples)
00254 {
00255 if( this->m_NumberOfFixedImageSamples == 0 )
00256 {
00257
00258 this->m_NumberOfFixedImageSamples = 1;
00259 }
00260 this->m_UseAllPixels = false;
00261 this->m_NumberOfFixedImageSamples = numSamples;
00262 this->Modified();
00263 }
00264 }
00266
00267 itkGetConstReferenceMacro( NumberOfFixedImageSamples, unsigned long );
00268 void SetNumberOfSpatialSamples( unsigned long num )
00269 {
00270 this->SetNumberOfFixedImageSamples( num );
00271 }
00272 unsigned long GetNumberOfSpatialSamples( void )
00273 {
00274 return this->GetNumberOfFixedImageSamples();
00275 }
00276
00279 void SetFixedImageSamplesIntensityThreshold( const FixedImagePixelType & thresh );
00280 itkGetConstReferenceMacro( FixedImageSamplesIntensityThreshold, FixedImagePixelType );
00281 itkSetMacro( UseFixedImageSamplesIntensityThreshold, bool );
00282 itkGetConstReferenceMacro( UseFixedImageSamplesIntensityThreshold, bool );
00284
00287 itkSetMacro( UseAllPixels, bool );
00288 itkGetConstReferenceMacro( UseAllPixels, bool );
00289 itkBooleanMacro( UseAllPixels );
00291
00293 itkGetConstReferenceMacro( NumberOfPixelsCounted, unsigned long );
00294
00304 void ReinitializeSeed();
00305 void ReinitializeSeed( int seed );
00307
00324 itkSetMacro(UseCachingOfBSplineWeights,bool);
00325 itkGetConstReferenceMacro(UseCachingOfBSplineWeights,bool);
00326 itkBooleanMacro(UseCachingOfBSplineWeights);
00328
00329 protected:
00330 ImageToImageMetric();
00331 virtual ~ImageToImageMetric();
00332
00333 void PrintSelf(std::ostream& os, Indent indent) const;
00334
00335 mutable unsigned long m_NumberOfPixelsCounted;
00336
00340
00341 class FixedImageSamplePoint
00342 {
00343 public:
00344 FixedImageSamplePoint()
00345 {
00346 point.Fill(0.0);
00347 value = 0;
00348 valueIndex = 0;
00349 }
00350 ~FixedImageSamplePoint() {};
00351
00352 public:
00353 FixedImagePointType point;
00354 double value;
00355 unsigned int valueIndex;
00356 };
00358
00359 bool m_UseFixedImageIndexes;
00360 FixedImageIndexContainer m_FixedImageIndexes;
00361 FixedImagePixelType m_FixedImageSamplesIntensityThreshold;
00362 bool m_UseFixedImageSamplesIntensityThreshold;
00363
00365 typedef std::vector<FixedImageSamplePoint> FixedImageSampleContainer;
00366
00368 virtual void SampleFixedImageDomain( FixedImageSampleContainer & samples) const;
00369
00370 virtual void SampleFixedImageIndexes( FixedImageSampleContainer &
00371 samples);
00372
00374 virtual void SampleFullFixedImageDomain( FixedImageSampleContainer &
00375 samples);
00376
00378 FixedImageSampleContainer m_FixedImageSamples;
00379
00380 unsigned long m_NumberOfParameters;
00381 mutable ParametersType m_Parameters;
00382
00383 unsigned long m_NumberOfFixedImageSamples;
00384 mutable unsigned long m_NumberOfMovingImageSamples;
00385
00386 FixedImageConstPointer m_FixedImage;
00387 MovingImageConstPointer m_MovingImage;
00388
00390 TransformPointer m_Transform;
00391
00394 TransformPointer * m_ThreaderTransform;
00395
00396 InterpolatorPointer m_Interpolator;
00397
00398 bool m_ComputeGradient;
00399 GradientImagePointer m_GradientImage;
00400
00401 FixedImageMaskPointer m_FixedImageMask;
00402 MovingImageMaskPointer m_MovingImageMask;
00403
00404 unsigned int m_NumberOfThreads;
00405
00406 bool m_UseAllPixels;
00407
00408 bool m_ReseedIterator;
00409
00410 int m_RandomSeed;
00411
00419 bool m_TransformIsBSpline;
00420
00423 unsigned long m_NumBSplineWeights;
00424
00425 itkStaticConstMacro(DeformationSplineOrder, unsigned int, 3 );
00426
00427 typedef BSplineDeformableTransform< CoordinateRepresentationType,
00428 ::itk::GetImageDimension<FixedImageType>::ImageDimension,
00429 itkGetStaticConstMacro(DeformationSplineOrder) > BSplineTransformType;
00430
00431 typedef typename BSplineTransformType::WeightsType BSplineTransformWeightsType;
00432 typedef typename BSplineTransformWeightsType::ValueType WeightsValueType;
00433 typedef Array2D<WeightsValueType> BSplineTransformWeightsArrayType;
00434
00435 typedef typename BSplineTransformType::ParameterIndexArrayType
00436 BSplineTransformIndexArrayType;
00437 typedef typename BSplineTransformIndexArrayType::ValueType IndexValueType;
00438 typedef Array2D<IndexValueType> BSplineTransformIndicesArrayType;
00439
00440 typedef std::vector<MovingImagePointType> MovingImagePointArrayType;
00441 typedef std::vector<bool> BooleanArrayType;
00442 typedef FixedArray< unsigned long,
00443 ::itk::GetImageDimension<FixedImageType>
00444 ::ImageDimension > BSplineParametersOffsetType;
00450 typedef BSplineInterpolateImageFunction<MovingImageType,
00451 CoordinateRepresentationType>
00452 BSplineInterpolatorType;
00453
00455 typedef CentralDifferenceImageFunction<MovingImageType,
00456 CoordinateRepresentationType>
00457 DerivativeFunctionType;
00458 typedef CovariantVector< double,
00459 itkGetStaticConstMacro(MovingImageDimension) >
00460 ImageDerivativesType;
00461
00462
00463 typename BSplineTransformType::Pointer m_BSplineTransform;
00464
00465 BSplineTransformWeightsArrayType m_BSplineTransformWeightsArray;
00466 BSplineTransformIndicesArrayType m_BSplineTransformIndicesArray;
00467 MovingImagePointArrayType m_BSplinePreTransformPointsArray;
00468 BooleanArrayType m_WithinBSplineSupportRegionArray;
00469
00470 BSplineParametersOffsetType m_BSplineParametersOffset;
00471
00472
00473 bool m_UseCachingOfBSplineWeights;
00474 mutable BSplineTransformWeightsType m_BSplineTransformWeights;
00475 mutable BSplineTransformIndexArrayType m_BSplineTransformIndices;
00476
00477 mutable BSplineTransformWeightsType * m_ThreaderBSplineTransformWeights;
00478 mutable BSplineTransformIndexArrayType * m_ThreaderBSplineTransformIndices;
00479
00480 virtual void PreComputeTransformValues( void );
00481
00484 virtual void TransformPoint( unsigned int sampleNumber,
00485 MovingImagePointType& mappedPoint,
00486 bool& sampleWithinSupportRegion,
00487 double& movingImageValue,
00488 unsigned int threadID ) const;
00489
00490 virtual void TransformPointWithDerivatives( unsigned int sampleNumber,
00491 MovingImagePointType& mappedPoint,
00492 bool& sampleWithinSupportRegion,
00493 double& movingImageValue,
00494 ImageDerivativesType & gradient,
00495 unsigned int threadID ) const;
00496
00498 bool m_InterpolatorIsBSpline;
00499
00501 typename BSplineInterpolatorType::Pointer m_BSplineInterpolator;
00502
00504 typename DerivativeFunctionType::Pointer m_DerivativeCalculator;
00505
00507 virtual void ComputeImageDerivatives(
00508 const MovingImagePointType & mappedPoint,
00509 ImageDerivativesType & gradient,
00510 unsigned int threadID ) const;
00511
00512
00517 typedef MultiThreader MultiThreaderType;
00518
00519 struct MultiThreaderParameterType
00520 {
00521 ImageToImageMetric * metric;
00522 };
00523
00524 MultiThreaderType::Pointer m_Threader;
00525 MultiThreaderParameterType m_ThreaderParameter;
00526 mutable unsigned int m_ThreaderChunkSize;
00527 mutable unsigned int m_ThreaderSizeOfLastChunk;
00528 mutable unsigned int * m_ThreaderNumberOfMovingImageSamples;
00529 bool m_WithinThreadPreProcess;
00530 bool m_WithinThreadPostProcess;
00531
00532 void GetValueMultiThreadedPreProcessInitiate(
00533 void ) const;
00534 void GetValueMultiThreadedInitiate( void ) const;
00535 void GetValueMultiThreadedPostProcessInitiate(
00536 void ) const;
00537 static ITK_THREAD_RETURN_TYPE GetValueMultiThreadedPreProcess( void * arg );
00538 static ITK_THREAD_RETURN_TYPE GetValueMultiThreaded( void * arg );
00539 static ITK_THREAD_RETURN_TYPE GetValueMultiThreadedPostProcess( void * arg );
00540
00541 void GetValueThread( unsigned int threadID ) const;
00542 virtual inline void GetValueThreadPreProcess(
00543 unsigned int threadID,
00544 bool withinSampleThread ) const;
00545 virtual inline bool GetValueThreadProcessSample(
00546 unsigned int itkNotUsed(threadID),
00547 unsigned long itkNotUsed(fixedImageSample),
00548 const MovingImagePointType & itkNotUsed(mappedPoint),
00549 double itkNotUsed(movingImageValue)) const
00550 { return false; };
00551 virtual inline void GetValueThreadPostProcess(
00552 unsigned int itkNotUsed(threadID),
00553 bool itkNotUsed(withinSampleThread) ) const {};
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 void GetValueAndDerivativeMultiThreadedPreProcessInitiate(
00567 void) const;
00568 void GetValueAndDerivativeMultiThreadedInitiate( void) const;
00569 void GetValueAndDerivativeMultiThreadedPostProcessInitiate(
00570 void) const;
00571 static ITK_THREAD_RETURN_TYPE
00572 GetValueAndDerivativeMultiThreadedPreProcess(void * arg);
00573
00574 static ITK_THREAD_RETURN_TYPE
00575 GetValueAndDerivativeMultiThreaded(void * arg);
00576
00577 static ITK_THREAD_RETURN_TYPE
00578 GetValueAndDerivativeMultiThreadedPostProcess(void * arg);
00579
00580 void GetValueAndDerivativeThread(unsigned int threadID) const;
00581 virtual inline void GetValueAndDerivativeThreadPreProcess( unsigned int itkNotUsed(threadID),
00582 bool itkNotUsed(withinSampleThread)) const {};
00583 virtual inline bool GetValueAndDerivativeThreadProcessSample(
00584 unsigned int itkNotUsed(threadID),
00585 unsigned long itkNotUsed(fixedImageSample),
00586 const MovingImagePointType & itkNotUsed(mappedPoint),
00587 double itkNotUsed(movingImageValue),
00588 const ImageDerivativesType & itkNotUsed(movingImageGradientValue) ) const
00589 {
00590 return false;
00591 }
00592
00593 virtual inline void GetValueAndDerivativeThreadPostProcess(
00594 unsigned int itkNotUsed(threadID),
00595 bool itkNotUsed(withinSampleThread) ) const {};
00596
00600 void SynchronizeTransforms() const;
00601
00603 void NumberOfFixedImageSamplesUpdated();
00604
00605 private:
00606 ImageToImageMetric(const Self&);
00607 void operator=(const Self&);
00608
00609 FixedImageRegionType m_FixedImageRegion;
00610
00611 };
00612
00613 }
00614
00615 #ifndef ITK_MANUAL_INSTANTIATION
00616 #include "itkOptImageToImageMetric.txx"
00617 #endif
00618
00619 #endif
00620