ITK  4.1.0
Insight Segmentation and Registration Toolkit
itkImageToImageMetric.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 #ifndef __itkImageToImageMetric_h
00019 #define __itkImageToImageMetric_h
00020 
00021 #include "itkBSplineBaseTransform.h"
00022 #include "itkBSplineInterpolateImageFunction.h"
00023 #include "itkSingleValuedCostFunction.h"
00024 #include "itkGradientRecursiveGaussianImageFilter.h"
00025 #include "itkSpatialObject.h"
00026 #include "itkCentralDifferenceImageFunction.h"
00027 
00028 namespace itk
00029 {
00050 template< class TFixedImage,  class TMovingImage >
00051 class ITK_EXPORT ImageToImageMetric:
00052   public SingleValuedCostFunction
00053 {
00054 public:
00056   typedef ImageToImageMetric         Self;
00057   typedef SingleValuedCostFunction   Superclass;
00058   typedef SmartPointer< Self >       Pointer;
00059   typedef SmartPointer< const Self > ConstPointer;
00060 
00062   typedef typename Superclass::ParametersValueType CoordinateRepresentationType;
00063 
00065   itkTypeMacro(ImageToImageMetric, SingleValuedCostFunction);
00066 
00068   typedef TMovingImage                           MovingImageType;
00069   typedef typename TMovingImage::PixelType       MovingImagePixelType;
00070   typedef typename MovingImageType::ConstPointer MovingImageConstPointer;
00071 
00073   typedef TFixedImage                           FixedImageType;
00074   typedef typename TFixedImage::PixelType       FixedImagePixelType;
00075   typedef typename FixedImageType::ConstPointer FixedImageConstPointer;
00076   typedef typename FixedImageType::RegionType   FixedImageRegionType;
00077 
00079   itkStaticConstMacro(MovingImageDimension,
00080                       unsigned int,
00081                       TMovingImage::ImageDimension);
00082   itkStaticConstMacro(FixedImageDimension,
00083                       unsigned int,
00084                       TFixedImage::ImageDimension);
00086 
00088   typedef Transform< CoordinateRepresentationType,
00089                      itkGetStaticConstMacro(MovingImageDimension),
00090                      itkGetStaticConstMacro(FixedImageDimension) >
00091   TransformType;
00092 
00093   typedef typename TransformType::Pointer         TransformPointer;
00094   typedef typename TransformType::InputPointType  InputPointType;
00095   typedef typename TransformType::OutputPointType OutputPointType;
00096   typedef typename TransformType::ParametersType  TransformParametersType;
00097   typedef typename TransformType::JacobianType    TransformJacobianType;
00098 
00100   typedef typename FixedImageType::IndexType           FixedImageIndexType;
00101   typedef typename FixedImageIndexType::IndexValueType FixedImageIndexValueType;
00102   typedef typename MovingImageType::IndexType          MovingImageIndexType;
00103   typedef typename TransformType::InputPointType       FixedImagePointType;
00104   typedef typename TransformType::OutputPointType      MovingImagePointType;
00105 
00106   typedef std::vector< FixedImageIndexType > FixedImageIndexContainer;
00107 
00109   typedef InterpolateImageFunction< MovingImageType, CoordinateRepresentationType > InterpolatorType;
00110 
00112   typedef typename NumericTraits< MovingImagePixelType >::RealType                   RealType;
00113   typedef CovariantVector< RealType, itkGetStaticConstMacro(MovingImageDimension) >  GradientPixelType;
00114   typedef Image< GradientPixelType, itkGetStaticConstMacro(MovingImageDimension) >   GradientImageType;
00115   typedef SmartPointer< GradientImageType >                                          GradientImagePointer;
00116   typedef GradientRecursiveGaussianImageFilter< MovingImageType, GradientImageType > GradientImageFilterType;
00117   typedef typename GradientImageFilterType::Pointer                                  GradientImageFilterPointer;
00119 
00120   typedef typename InterpolatorType::Pointer InterpolatorPointer;
00121 
00124   typedef SpatialObject< itkGetStaticConstMacro(FixedImageDimension) > FixedImageMaskType;
00125   typedef typename FixedImageMaskType::Pointer                         FixedImageMaskPointer;
00126   typedef typename FixedImageMaskType::ConstPointer                    FixedImageMaskConstPointer;
00127 
00130   typedef SpatialObject< itkGetStaticConstMacro(MovingImageDimension) > MovingImageMaskType;
00131   typedef typename MovingImageMaskType::Pointer                         MovingImageMaskPointer;
00132   typedef typename MovingImageMaskType::ConstPointer                    MovingImageMaskConstPointer;
00133 
00135   typedef typename Superclass::MeasureType MeasureType;
00136 
00138   typedef typename Superclass::DerivativeType DerivativeType;
00139 
00141   typedef typename Superclass::ParametersType ParametersType;
00142 
00144   itkSetConstObjectMacro( FixedImage, FixedImageType );
00145 
00147   itkGetConstObjectMacro( FixedImage, FixedImageType );
00148 
00150   itkSetConstObjectMacro( MovingImage, MovingImageType );
00151 
00153   itkGetConstObjectMacro( MovingImage, MovingImageType );
00154 
00156   itkSetObjectMacro( Transform, TransformType );
00157 
00159   itkGetConstObjectMacro(Transform, TransformType);
00160 
00162   itkSetObjectMacro(Interpolator, InterpolatorType);
00163 
00165   itkGetConstObjectMacro(Interpolator, InterpolatorType);
00166 
00168   SizeValueType GetNumberOfMovingImageSamples(void)
00169   {
00170     return this->GetNumberOfPixelsCounted();
00171   }
00172 
00173   itkGetConstReferenceMacro(NumberOfPixelsCounted, SizeValueType);
00174 
00176   void SetFixedImageRegion(const FixedImageRegionType reg);
00177 
00179   itkGetConstReferenceMacro(FixedImageRegion, FixedImageRegionType);
00180 
00182   itkSetObjectMacro(MovingImageMask, MovingImageMaskType);
00183   itkSetConstObjectMacro(MovingImageMask, MovingImageMaskType);
00184   itkGetConstObjectMacro(MovingImageMask, MovingImageMaskType);
00186 
00188   itkSetObjectMacro(FixedImageMask, FixedImageMaskType);
00189   itkSetConstObjectMacro(FixedImageMask, FixedImageMaskType);
00190   itkGetConstObjectMacro(FixedImageMask, FixedImageMaskType);
00192 
00195   void SetFixedImageIndexes(const FixedImageIndexContainer & indexes);
00196 
00197   void SetUseFixedImageIndexes(bool useIndex);
00198 
00199   itkGetConstReferenceMacro(UseFixedImageIndexes, bool);
00200 
00202   void SetNumberOfThreads(ThreadIdType numberOfThreads);
00203   itkGetConstReferenceMacro(NumberOfThreads, ThreadIdType);
00205 
00207   itkSetMacro(ComputeGradient, bool);
00208   itkGetConstReferenceMacro(ComputeGradient, bool);
00209   itkBooleanMacro(ComputeGradient);
00211 
00213   virtual void ComputeGradient(void);
00214 
00216   itkGetConstObjectMacro(GradientImage, GradientImageType);
00217 
00219   void SetTransformParameters(const ParametersType & parameters) const;
00220 
00222   unsigned int GetNumberOfParameters(void) const
00223   {
00224     return m_Transform->GetNumberOfParameters();
00225   }
00226 
00229   virtual void Initialize(void)
00230   throw ( ExceptionObject );
00231 
00233   virtual void MultiThreadingInitialize(void) throw ( ExceptionObject );
00234 
00237   virtual void SetNumberOfFixedImageSamples(SizeValueType numSamples);
00238   itkGetConstReferenceMacro(NumberOfFixedImageSamples, SizeValueType);
00240 
00243   void SetNumberOfSpatialSamples(SizeValueType num)
00244   {
00245     this->SetNumberOfFixedImageSamples(num);
00246   }
00247 
00248   SizeValueType GetNumberOfSpatialSamples(void)
00249   {
00250     return this->GetNumberOfFixedImageSamples();
00251   }
00252 
00255   void SetFixedImageSamplesIntensityThreshold(const FixedImagePixelType & thresh);
00256 
00257   itkGetConstReferenceMacro(FixedImageSamplesIntensityThreshold, FixedImagePixelType);
00258 
00259   void SetUseFixedImageSamplesIntensityThreshold(bool useThresh);
00260 
00261   itkGetConstReferenceMacro(UseFixedImageSamplesIntensityThreshold, bool);
00262 
00266   void SetUseAllPixels(bool useAllPixels);
00267 
00268   void UseAllPixelsOn(void)
00269   {
00270     this->SetUseAllPixels(true);
00271   }
00272 
00273   void UseAllPixelsOff(void)
00274   {
00275     this->SetUseAllPixels(false);
00276   }
00277 
00278   itkGetConstReferenceMacro(UseAllPixels, bool);
00279 
00284   void SetUseSequentialSampling(bool sequentialSampling);
00285 
00286   itkGetConstReferenceMacro(UseSequentialSampling, bool);
00287 
00297   void ReinitializeSeed();
00298   void ReinitializeSeed(int seed);
00300 
00317   itkSetMacro(UseCachingOfBSplineWeights, bool);
00318   itkGetConstReferenceMacro(UseCachingOfBSplineWeights, bool);
00319   itkBooleanMacro(UseCachingOfBSplineWeights);
00321 
00322   typedef MultiThreader MultiThreaderType;
00324   itkGetConstObjectMacro(Threader, MultiThreaderType);
00325   const TransformPointer * GetThreaderTransform()
00326   {
00327     return m_ThreaderTransform;
00328   }
00330 
00331 protected:
00332   ImageToImageMetric();
00333   virtual ~ImageToImageMetric();
00334 
00335   void PrintSelf(std::ostream & os, Indent indent) const;
00336 
00342   class FixedImageSamplePoint
00343   {
00344 public:
00345     FixedImageSamplePoint()
00346     {
00347       point.Fill(0.0);
00348       value = 0;
00349       valueIndex = 0;
00350     }
00351 
00352     ~FixedImageSamplePoint() {}
00353 public:
00354     FixedImagePointType point;
00355     double              value;
00356     unsigned int        valueIndex;
00357   };
00358 
00359   bool                     m_UseFixedImageIndexes;
00360   FixedImageIndexContainer m_FixedImageIndexes;
00361 
00362   bool                m_UseFixedImageSamplesIntensityThreshold;
00363   FixedImagePixelType m_FixedImageSamplesIntensityThreshold;
00364 
00366   typedef std::vector< FixedImageSamplePoint > FixedImageSampleContainer;
00367 
00369   virtual void SampleFixedImageRegion(FixedImageSampleContainer & samples) const;
00370 
00371   virtual void SampleFixedImageIndexes(FixedImageSampleContainer & samples) const;
00372 
00374   virtual void SampleFullFixedImageRegion(FixedImageSampleContainer &
00375                                           samples) const;
00376 
00378   FixedImageSampleContainer m_FixedImageSamples;
00379 
00380   SizeValueType          m_NumberOfParameters;
00381 
00382   SizeValueType m_NumberOfFixedImageSamples;
00383   //m_NumberOfPixelsCounted must be mutable because the const
00384   //thread consolidation functions merge each threads valus
00385   //onto this accumulator variable.
00386   mutable SizeValueType m_NumberOfPixelsCounted;
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   ThreadIdType m_NumberOfThreads;
00407 
00408   bool m_UseAllPixels;
00409   bool m_UseSequentialSampling;
00410 
00411   bool m_ReseedIterator;
00412 
00413   int m_RandomSeed;
00414 
00422   bool m_TransformIsBSpline;
00423 
00426   SizeValueType m_NumBSplineWeights;
00427 
00428   itkStaticConstMacro(DeformationSplineOrder, unsigned int, 3);
00429 
00430   typedef BSplineBaseTransform< CoordinateRepresentationType,
00431                                       ::itk::GetImageDimension< FixedImageType >::ImageDimension,
00432                                       itkGetStaticConstMacro(DeformationSplineOrder) >             BSplineTransformType;
00433 
00434   typedef typename BSplineTransformType::WeightsType      BSplineTransformWeightsType;
00435   typedef typename BSplineTransformWeightsType::ValueType WeightsValueType;
00436   typedef          Array2D< WeightsValueType >            BSplineTransformWeightsArrayType;
00437 
00438   typedef typename BSplineTransformType::ParameterIndexArrayType 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< SizeValueType, ::itk::GetImageDimension< FixedImageType >::ImageDimension > BSplineParametersOffsetType;
00450   typedef BSplineInterpolateImageFunction< MovingImageType,
00451                                            CoordinateRepresentationType >
00452   BSplineInterpolatorType;
00453 
00455   typedef CentralDifferenceImageFunction< MovingImageType,
00456                                           CoordinateRepresentationType >
00457   DerivativeFunctionType;
00458   typedef CovariantVector< double, itkGetStaticConstMacro(MovingImageDimension) >
00459   ImageDerivativesType;
00460 
00461   typename BSplineTransformType::Pointer m_BSplineTransform;
00462 
00463   BSplineTransformWeightsArrayType m_BSplineTransformWeightsArray;
00464   BSplineTransformIndicesArrayType m_BSplineTransformIndicesArray;
00465   MovingImagePointArrayType        m_BSplinePreTransformPointsArray;
00466   BooleanArrayType                 m_WithinBSplineSupportRegionArray;
00467 
00468   BSplineParametersOffsetType m_BSplineParametersOffset;
00469 
00470   // Variables needed for optionally caching values when using a BSpline
00471   // transform.
00472   bool                                   m_UseCachingOfBSplineWeights;
00473   mutable BSplineTransformWeightsType    m_BSplineTransformWeights;
00474   mutable BSplineTransformIndexArrayType m_BSplineTransformIndices;
00475 
00476   mutable BSplineTransformWeightsType    *m_ThreaderBSplineTransformWeights;
00477   mutable BSplineTransformIndexArrayType *m_ThreaderBSplineTransformIndices;
00478 
00479   virtual void PreComputeTransformValues(void);
00480 
00483   virtual void TransformPoint(unsigned int sampleNumber,
00484                               MovingImagePointType & mappedPoint,
00485                               bool & sampleWithinSupportRegion,
00486                               double & movingImageValue,
00487                               ThreadIdType threadID) const;
00488 
00489   virtual void TransformPointWithDerivatives(unsigned int sampleNumber,
00490                                              MovingImagePointType & mappedPoint,
00491                                              bool & sampleWithinSupportRegion,
00492                                              double & movingImageValue,
00493                                              ImageDerivativesType & gradient,
00494                                              ThreadIdType threadID) const;
00495 
00497   bool m_InterpolatorIsBSpline;
00498 
00500   typename BSplineInterpolatorType::Pointer m_BSplineInterpolator;
00501 
00503   typename DerivativeFunctionType::Pointer m_DerivativeCalculator;
00504 
00506   virtual void ComputeImageDerivatives(const MovingImagePointType & mappedPoint,
00507                                        ImageDerivativesType & gradient,
00508                                        ThreadIdType threadID) const;
00509 
00514   struct MultiThreaderParameterType {
00515     ImageToImageMetric *metric;
00516   };
00517 
00518   MultiThreaderType::Pointer m_Threader;
00519   MultiThreaderParameterType m_ThreaderParameter;
00520   mutable unsigned int *     m_ThreaderNumberOfMovingImageSamples;
00521   bool                       m_WithinThreadPreProcess;
00522   bool                       m_WithinThreadPostProcess;
00523 
00524   void                           GetValueMultiThreadedPreProcessInitiate(void) const;
00525 
00526   void                           GetValueMultiThreadedInitiate(void) const;
00527 
00528   void                           GetValueMultiThreadedPostProcessInitiate(void) const;
00529 
00530   static ITK_THREAD_RETURN_TYPE  GetValueMultiThreadedPreProcess(void *arg);
00531 
00532   static ITK_THREAD_RETURN_TYPE  GetValueMultiThreaded(void *arg);
00533 
00534   static ITK_THREAD_RETURN_TYPE  GetValueMultiThreadedPostProcess(void *arg);
00535 
00536   virtual inline void       GetValueThread(ThreadIdType threadID) const;
00537 
00538   virtual inline void       GetValueThreadPreProcess(
00539     ThreadIdType itkNotUsed(threadID),
00540     bool itkNotUsed(withinSampleThread) ) const
00541   {}
00542   virtual inline bool       GetValueThreadProcessSample(
00543     ThreadIdType itkNotUsed(threadID),
00544     SizeValueType itkNotUsed(fixedImageSample),
00545     const MovingImagePointType & itkNotUsed(mappedPoint),
00546     double itkNotUsed(movingImageValue) ) const
00547   { return false; }
00548   virtual inline void       GetValueThreadPostProcess(
00549     ThreadIdType itkNotUsed(threadID),
00550     bool itkNotUsed(withinSampleThread) ) const
00551   {}
00552 
00553   void                          GetValueAndDerivativeMultiThreadedPreProcessInitiate(void) const;
00554 
00555   void                          GetValueAndDerivativeMultiThreadedInitiate(void) const;
00556 
00557   void                          GetValueAndDerivativeMultiThreadedPostProcessInitiate(void) const;
00558 
00559   static ITK_THREAD_RETURN_TYPE GetValueAndDerivativeMultiThreadedPreProcess(void *arg);
00560 
00561   static ITK_THREAD_RETURN_TYPE GetValueAndDerivativeMultiThreaded(void *arg);
00562 
00563   static ITK_THREAD_RETURN_TYPE GetValueAndDerivativeMultiThreadedPostProcess(void *arg);
00564 
00565   virtual inline void  GetValueAndDerivativeThread(ThreadIdType threadID) const;
00566 
00567   virtual inline void  GetValueAndDerivativeThreadPreProcess(
00568     ThreadIdType itkNotUsed(threadID),
00569     bool itkNotUsed(withinSampleThread) ) const
00570   {}
00571   virtual inline bool  GetValueAndDerivativeThreadProcessSample(
00572     ThreadIdType itkNotUsed(threadID),
00573     SizeValueType itkNotUsed(fixedImageSample),
00574     const MovingImagePointType & itkNotUsed(mappedPoint),
00575     double itkNotUsed(movingImageValue),
00576     const ImageDerivativesType & itkNotUsed(movingImageGradientValue) ) const
00577   { return false; }
00578   virtual inline void  GetValueAndDerivativeThreadPostProcess(
00579     ThreadIdType itkNotUsed(threadID),
00580     bool itkNotUsed(withinSampleThread) ) const
00581   {}
00582 
00586   virtual void SynchronizeTransforms() const;
00587 
00588 private:
00589   ImageToImageMetric(const Self &); //purposely not implemented
00590   void operator=(const Self &);     //purposely not implemented
00591 
00592   FixedImageRegionType m_FixedImageRegion;
00593 };
00594 } // end namespace itk
00595 
00596 #ifndef ITK_MANUAL_INSTANTIATION
00597 #include "itkImageToImageMetric.hxx"
00598 #endif
00599 
00600 #endif
00601