00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkMRIBiasFieldCorrectionFilter_h
00018 #define __itkMRIBiasFieldCorrectionFilter_h
00019
00020 #include "itkImageToImageFilter.h"
00021 #include "itkImage.h"
00022
00023 #include "itkMRASlabIdentifier.h"
00024 #include "itkCompositeValleyFunction.h"
00025 #include "itkMultivariateLegendrePolynomial.h"
00026 #include "Statistics/itkNormalVariateGenerator.h"
00027 #include "itkOnePlusOneEvolutionaryOptimizer.h"
00028 #include "itkArray.h"
00029 #include "itkImageRegionConstIterator.h"
00030
00031
00032 namespace itk
00033 {
00045 template<class TImage, class TImageMask, class TBiasField>
00046 class MRIBiasEnergyFunction : public SingleValuedCostFunction
00047 {
00048 public:
00050 typedef MRIBiasEnergyFunction Self;
00051 typedef SingleValuedCostFunction Superclass;
00052 typedef SmartPointer<Self> Pointer;
00053 typedef SmartPointer<const Self> ConstPointer;
00054
00056 itkNewMacro(Self);
00057
00059 itkTypeMacro( SingleValuedCostFunction, CostFunction );
00060
00061
00063 typedef TImage ImageType ;
00064 typedef TImageMask MaskType ;
00065 typedef typename ImageType::Pointer ImagePointer ;
00066 typedef typename MaskType::Pointer MaskPointer ;
00067 typedef typename ImageType::PixelType ImageElementType ;
00068 typedef typename MaskType::PixelType MaskElementType ;
00069 typedef typename ImageType::IndexType ImageIndexType ;
00070 typedef typename ImageType::RegionType ImageRegionType ;
00071
00073 typedef TBiasField BiasFieldType;
00074
00077 typedef typename Superclass::ParametersType ParametersType ;
00078
00080 typedef Superclass::DerivativeType DerivativeType;
00081
00083 typedef Superclass::MeasureType MeasureType;
00084
00086 itkStaticConstMacro(SpaceDimension, unsigned int, 3);
00087
00089 typedef CompositeValleyFunction InternalEnergyFunction ;
00090
00092 itkSetObjectMacro( Image, ImageType );
00093
00095 itkSetObjectMacro( Mask, MaskType );
00096
00098 itkSetMacro( Region, ImageRegionType );
00099
00101 itkSetObjectMacro( BiasField, BiasFieldType );
00102
00105 double GetEnergy0(double diff)
00106 { return (*m_InternalEnergyFunction)(diff); }
00107
00110 MeasureType GetValue(const ParametersType & parameters ) const ;
00111
00114 void GetDerivative( const ParametersType & itkNotUsed(parameters),
00115 DerivativeType & itkNotUsed(derivative) ) const
00116 { }
00117
00122 void InitializeDistributions( Array<double> classMeans,
00123 Array<double> classSigmas );
00124
00125 unsigned int GetNumberOfParameters(void) const;
00126
00127 private:
00129 BiasFieldType * m_BiasField ;
00130
00132 ImagePointer m_Image ;
00133
00135 MaskPointer m_Mask ;
00136
00138 ImageRegionType m_Region ;
00139
00141 InternalEnergyFunction* m_InternalEnergyFunction ;
00142
00143 protected:
00145 MRIBiasEnergyFunction();
00146
00148 virtual ~MRIBiasEnergyFunction();
00149
00150
00151 private:
00152
00153 MRIBiasEnergyFunction(const Self&);
00154 void operator=(const Self&);
00155
00156 } ;
00157
00158
00159
00197 template <class TInputImage, class TOutputImage, class TMaskImage>
00198 class ITK_EXPORT MRIBiasFieldCorrectionFilter :
00199 public ImageToImageFilter< TInputImage, TOutputImage >
00200 {
00201 public:
00203 typedef MRIBiasFieldCorrectionFilter Self;
00204 typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass;
00205 typedef SmartPointer<Self> Pointer;
00206 typedef SmartPointer<const Self> ConstPointer;
00207
00209 itkNewMacro(Self);
00210
00212 itkTypeMacro(MRIBiasFieldCorrectionFilter, ImageToImageFilter);
00213
00215 itkStaticConstMacro(ImageDimension, unsigned int,
00216 TOutputImage::ImageDimension);
00217
00219 typedef TOutputImage OutputImageType ;
00220 typedef TInputImage InputImageType ;
00221 typedef typename TOutputImage::Pointer OutputImagePointer ;
00222 typedef typename TOutputImage::IndexType OutputImageIndexType ;
00223 typedef typename TOutputImage::PixelType OutputImagePixelType ;
00224 typedef typename TOutputImage::SizeType OutputImageSizeType;
00225 typedef typename TOutputImage::RegionType OutputImageRegionType;
00226 typedef typename TInputImage::Pointer InputImagePointer ;
00227 typedef typename TInputImage::IndexType InputImageIndexType;
00228 typedef typename TInputImage::PixelType InputImagePixelType;
00229 typedef typename TInputImage::SizeType InputImageSizeType;
00230 typedef typename TInputImage::RegionType InputImageRegionType;
00231
00233 typedef TMaskImage ImageMaskType ;
00234 typedef typename ImageMaskType::Pointer ImageMaskPointer ;
00235 typedef typename ImageMaskType::RegionType ImageMaskRegionType ;
00236
00238 typedef Image< float, itkGetStaticConstMacro(ImageDimension) > InternalImageType ;
00239 typedef typename InternalImageType::PixelType InternalImagePixelType ;
00240 typedef typename InternalImageType::Pointer InternalImagePointer ;
00241 typedef typename InternalImageType::RegionType InternalImageRegionType ;
00242
00244 typedef MRASlabIdentifier<InputImageType> MRASlabIdentifierType;
00245 typedef typename MRASlabIdentifierType::SlabRegionVectorType
00246 SlabRegionVectorType;
00247 typedef typename SlabRegionVectorType::iterator SlabRegionVectorIteratorType;
00248
00250 typedef MultivariateLegendrePolynomial BiasFieldType;
00251
00253 typedef MRIBiasEnergyFunction<InternalImageType, ImageMaskType, BiasFieldType>
00254 EnergyFunctionType;
00255 typedef typename EnergyFunctionType::Pointer EnergyFunctionPointer;
00256
00258 typedef Statistics::NormalVariateGenerator NormalVariateGeneratorType ;
00259
00261 typedef OnePlusOneEvolutionaryOptimizer OptimizerType ;
00262
00266 void SetInputMask(ImageMaskPointer inputMask);
00267 itkGetObjectMacro( InputMask, ImageMaskType );
00268
00271 void SetOutputMask(ImageMaskPointer outputMask) ;
00272
00274 itkGetObjectMacro( OutputMask, ImageMaskType );
00275
00279 void IsBiasFieldMultiplicative(bool flag)
00280 { m_BiasMultiplicative = flag ; }
00281
00283 bool IsBiasFieldMultiplicative()
00284 { return m_BiasMultiplicative ; }
00285
00289 itkSetMacro( UsingInterSliceIntensityCorrection, bool );
00290
00296 itkSetMacro( UsingSlabIdentification, bool );
00297
00303 itkSetMacro( UsingBiasFieldCorrection, bool );
00304
00307 itkSetMacro( GeneratingOutput, bool );
00308
00311 itkSetMacro( SlicingDirection , int );
00312
00314 itkSetMacro( BiasFieldDegree, int );
00315 itkGetMacro( BiasFieldDegree, int );
00316
00318 itkGetMacro( NoOfBiasFieldCoefficients, int );
00319
00321 itkGetMacro( BiasFieldDomainSize, BiasFieldType::DomainSizeType );
00322
00325 void SetInitialBiasFieldCoefficients
00326 (const BiasFieldType::CoefficientArrayType &coefficients)
00327 { m_BiasFieldCoefficients = coefficients ; }
00328
00332 itkGetMacro( EstimatedBiasFieldCoefficients, BiasFieldType::CoefficientArrayType );
00333
00337 void SetTissueClassStatistics(const Array<double> & means,
00338 const Array<double> & sigmas)
00339 throw (ExceptionObject) ;
00340
00342 itkSetMacro( VolumeCorrectionMaximumIteration, int );
00343 itkGetMacro( VolumeCorrectionMaximumIteration, int );
00344 itkSetMacro( InterSliceCorrectionMaximumIteration, int );
00345 itkGetMacro( InterSliceCorrectionMaximumIteration, int );
00346
00348 void SetOptimizerInitialRadius(double initRadius)
00349 { m_OptimizerInitialRadius = initRadius ; }
00350 double GetOptimizerInitialRadius()
00351 { return m_OptimizerInitialRadius ; }
00352
00354 itkSetMacro( OptimizerGrowthFactor, double );
00355 itkGetMacro( OptimizerGrowthFactor, double );
00356
00359 itkSetMacro( OptimizerShrinkFactor, double );
00360 itkGetMacro( OptimizerShrinkFactor, double );
00361
00368 void Initialize() throw (ExceptionObject) ;
00369
00372 void EstimateBiasField(BiasFieldType* bias,
00373 InputImageRegionType region) ;
00374
00378 void CorrectImage(BiasFieldType* bias,
00379 InputImageRegionType region) ;
00380
00383 void CorrectInterSliceIntensityInhomogeneity(InputImageRegionType region) ;
00384
00385 protected:
00386 MRIBiasFieldCorrectionFilter() ;
00387 virtual ~MRIBiasFieldCorrectionFilter() ;
00388
00391 bool CheckMaskImage(ImageMaskPointer mask) ;
00392
00393 protected:
00397 void Log1PImage(InternalImagePointer source,
00398 InternalImagePointer target) ;
00399
00402 void ExpImage(InternalImagePointer source,
00403 InternalImagePointer target) ;
00404
00409 void GetBiasFieldSize(InputImageRegionType region,
00410 BiasFieldType::DomainSizeType& domainSize) ;
00411
00415 void AdjustSlabRegions(SlabRegionVectorType& slabs,
00416 OutputImageRegionType requestedRegion) ;
00417
00418 void GenerateData() ;
00419
00420 private:
00421 MRIBiasFieldCorrectionFilter(const Self&);
00422 void operator=(const Self&);
00423
00425 EnergyFunctionPointer m_EnergyFunction ;
00426
00428 NormalVariateGeneratorType::Pointer m_NormalVariateGenerator ;
00429
00431 OptimizerType::Pointer m_Optimizer ;
00432
00434 ImageMaskPointer m_InputMask ;
00435
00437 ImageMaskPointer m_OutputMask ;
00438
00440 InternalImagePointer m_InternalInput ;
00441
00443 SlabRegionVectorType m_Slabs ;
00444
00446 int m_SlicingDirection ;
00447
00449 bool m_BiasMultiplicative ;
00450
00452 bool m_UsingInterSliceIntensityCorrection ;
00453 bool m_UsingSlabIdentification ;
00454 bool m_UsingBiasFieldCorrection ;
00455 bool m_GeneratingOutput ;
00456
00458 int m_BiasFieldDegree ;
00459
00461 int m_BiasFieldDimension ;
00462
00464 int m_NoOfBiasFieldCoefficients ;
00465
00467 BiasFieldType::DomainSizeType m_BiasFieldDomainSize ;
00468
00471 BiasFieldType::CoefficientArrayType m_BiasFieldCoefficients ;
00472
00475 BiasFieldType::CoefficientArrayType m_EstimatedBiasFieldCoefficients ;
00476
00478 int m_VolumeCorrectionMaximumIteration ;
00479
00481 int m_InterSliceCorrectionMaximumIteration ;
00482
00484 double m_OptimizerInitialRadius ;
00485
00487 double m_OptimizerGrowthFactor ;
00488
00490 double m_OptimizerShrinkFactor ;
00491
00493 Array<double> m_TissueClassMeans ;
00494
00496 Array<double> m_TissueClassSigmas ;
00497 };
00498
00499
00500
00501
00504 template<class TSource, class TTarget>
00505 void CopyAndConvertImage(const TSource * sourceInp,
00506 TTarget * targetInp,
00507 typename TTarget::RegionType requestedRegion)
00508 {
00509 typedef ImageRegionConstIterator<TSource> SourceIterator ;
00510 typedef ImageRegionIterator<TTarget> TargetIterator ;
00511 typedef typename TTarget::PixelType TargetPixelType ;
00512
00513 typename TSource::ConstPointer source( sourceInp );
00514 typename TTarget::Pointer target( targetInp );
00515
00516 target->SetRequestedRegion(requestedRegion) ;
00517 target->SetBufferedRegion(requestedRegion) ;
00518 target->Allocate() ;
00519
00520 SourceIterator s_iter(source, requestedRegion) ;
00521 TargetIterator t_iter(target, requestedRegion) ;
00522
00523 s_iter.GoToBegin() ;
00524 t_iter.GoToBegin() ;
00525 while (!s_iter.IsAtEnd())
00526 {
00527 t_iter.Set(static_cast<TargetPixelType>( s_iter.Get() ) ) ;
00528 ++s_iter ;
00529 ++t_iter ;
00530 }
00531 }
00532
00533 }
00534
00535 #ifndef ITK_MANUAL_INSTANTIATION
00536 #include "itkMRIBiasFieldCorrectionFilter.txx"
00537 #endif
00538
00539 #endif