00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkAnisotropicDiffusionImageFilter_h_
00018 #define __itkAnisotropicDiffusionImageFilter_h_
00019
00020 #include "itkDenseFiniteDifferenceImageFilter.h"
00021 #include "itkAnisotropicDiffusionFunction.h"
00022 #include "itkNumericTraits.h"
00023
00024 namespace itk {
00025
00063 template <class TInputImage, class TOutputImage>
00064 class AnisotropicDiffusionImageFilter
00065 : public DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
00066 {
00067 public:
00069 typedef AnisotropicDiffusionImageFilter Self;
00070 typedef DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
00071 Superclass;
00072 typedef SmartPointer<Self> Pointer;
00073 typedef SmartPointer<const Self> ConstPointer;
00074
00076 itkTypeMacro(AnisotropicDiffusionImageFilter,
00077 DenseFiniteDifferenceImageFilter);
00078
00080 typedef typename Superclass::InputImageType InputImageType;
00081 typedef typename Superclass::OutputImageType OutputImageType;
00082 typedef typename Superclass::UpdateBufferType UpdateBufferType;
00083
00086 itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension);
00087
00090 typedef typename Superclass::PixelType PixelType;
00091 typedef typename Superclass::TimeStepType TimeStepType;
00092
00094 itkSetMacro(Iterations, unsigned int);
00095 itkGetMacro(Iterations, unsigned int);
00096
00098 itkSetMacro(TimeStep, TimeStepType);
00099 itkGetMacro(TimeStep, TimeStepType);
00100
00103 itkSetMacro(ConductanceParameter, double);
00104 itkGetMacro(ConductanceParameter, double);
00105
00108 itkSetMacro(ConductanceScalingUpdateInterval, unsigned int);
00109 itkGetMacro(ConductanceScalingUpdateInterval, unsigned int);
00110 itkSetMacro(ConductanceScalingParameter, double);
00111 itkGetMacro(ConductanceScalingParameter, double);
00112
00120 void SetFixedAverageGradientMagnitude(double a)
00121 {
00122 m_FixedAverageGradientMagnitude= a;
00123 this->Modified();
00124 m_GradientMagnitudeIsFixed = true;
00125 }
00126 itkGetMacro(FixedAverageGradientMagnitude, double);
00127
00128 protected:
00129 AnisotropicDiffusionImageFilter()
00130 {
00131 m_Iterations = 0;
00132 m_ConductanceParameter = 1.0;
00133 m_TimeStep = 0.125f;
00134 m_FixedAverageGradientMagnitude = 0.0;
00135 m_GradientMagnitudeIsFixed = false;
00136 }
00137 ~AnisotropicDiffusionImageFilter() {}
00138 void PrintSelf(std::ostream& os, Indent indent) const
00139 {
00140 Superclass::PrintSelf(os, indent.GetNextIndent());
00141 os << indent << "TimeStep: " << m_TimeStep << std::endl;
00142 os << indent << "ConductanceParameter: "
00143 << m_ConductanceParameter << std::endl;
00144 os << indent << "ConductanceScalingParameter: "
00145 << m_ConductanceScalingParameter << std::endl;
00146 os << indent << "Iterations: " << m_Iterations
00147 << std::endl;
00148 os << indent << "ConductanceScalingUpdateInterval: "
00149 << m_ConductanceScalingUpdateInterval << std::endl;
00150 os << indent << "FixedAverageGradientMagnitude: "
00151 << m_FixedAverageGradientMagnitude << std::endl;
00152 }
00153
00156 virtual bool Halt()
00157 {
00158 if (this->GetElapsedIterations() == m_Iterations) return true;
00159 else return false;
00160 }
00161
00163 virtual void InitializeIteration()
00164 {
00165 AnisotropicDiffusionFunction<UpdateBufferType> *f =
00166 dynamic_cast<AnisotropicDiffusionFunction<UpdateBufferType> *>
00167 (this->GetDifferenceFunction().GetPointer());
00168 if (! f)
00169 { throw ExceptionObject(__FILE__, __LINE__); }
00170
00171 f->SetConductanceParameter(m_ConductanceParameter);
00172 f->SetTimeStep(m_TimeStep);
00173
00174 if ( m_TimeStep > 1.0 / pow(2.0, static_cast<double>(ImageDimension)) )
00175 {
00176 f->SetTimeStep(1.0 / pow(2.0, static_cast<double>(ImageDimension)));
00177 itkWarningMacro(<< "Anisotropic diffusion has attempted to use a time step which will introduce instability into the solution. The time step has been automatically reduced to " << f->GetTimeStep() << ", which is the maximum value for which the solution is theoretically stable.");
00178 }
00179
00180 if (m_GradientMagnitudeIsFixed == false)
00181 {
00182 f->CalculateAverageGradientMagnitudeSquared(this->GetOutput());
00183 }
00184 else
00185 {
00186 f->SetAverageGradientMagnitudeSquared(m_FixedAverageGradientMagnitude
00187 *
00188 m_FixedAverageGradientMagnitude);
00189 }
00190 f->InitializeIteration();
00191
00192 if (m_Iterations != 0)
00193 this->UpdateProgress(((float)(this->GetElapsedIterations()))
00194 /((float)(m_Iterations)));
00195 else this->UpdateProgress(0);
00196 }
00197
00198 bool m_GradientMagnitudeIsFixed;
00199
00200 private:
00201 AnisotropicDiffusionImageFilter(const Self&);
00202 void operator=(const Self&);
00203
00204 double m_ConductanceParameter;
00205 double m_ConductanceScalingParameter;
00206 unsigned int m_Iterations;
00207 unsigned int m_ConductanceScalingUpdateInterval;
00208 double m_FixedAverageGradientMagnitude;
00209
00210 TimeStepType m_TimeStep;
00211
00212 };
00213
00214 }
00215
00216 #endif