ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkFastMarchingImageFilter.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 __itkFastMarchingImageFilter_h
00019 #define __itkFastMarchingImageFilter_h
00020 
00021 #include "itkImageToImageFilter.h"
00022 #include "itkImageRegionConstIteratorWithIndex.h"
00023 #include "itkLevelSet.h"
00024 #include "vnl/vnl_math.h"
00025 
00026 #include <functional>
00027 #include <queue>
00028 
00029 namespace itk
00030 {
00102 template<
00103   class TLevelSet,
00104   class TSpeedImage = Image< float, ::itk::GetImageDimension< TLevelSet >::ImageDimension > >
00105 class ITK_EXPORT FastMarchingImageFilter:
00106   public ImageToImageFilter< TSpeedImage, TLevelSet >
00107 {
00108 public:
00110   typedef FastMarchingImageFilter    Self;
00111   typedef ImageSource< TLevelSet >   Superclass;
00112   typedef SmartPointer< Self >       Pointer;
00113   typedef SmartPointer< const Self > ConstPointer;
00114 
00116   itkNewMacro(Self);
00117 
00119   itkTypeMacro(FastMarchingImageFilter, ImageSource);
00120 
00122   typedef LevelSetTypeDefault< TLevelSet >            LevelSetType;
00123   typedef typename LevelSetType::LevelSetImageType    LevelSetImageType;
00124   typedef typename LevelSetType::LevelSetPointer      LevelSetPointer;
00125   typedef typename LevelSetType::PixelType            PixelType;
00126   typedef typename LevelSetType::NodeType             NodeType;
00127   typedef typename NodeType::IndexType                NodeIndexType;
00128   typedef typename LevelSetType::NodeContainer        NodeContainer;
00129   typedef typename LevelSetType::NodeContainerPointer NodeContainerPointer;
00130   typedef typename LevelSetImageType::SizeType        OutputSizeType;
00131   typedef typename LevelSetImageType::RegionType      OutputRegionType;
00132   typedef typename LevelSetImageType::SpacingType     OutputSpacingType;
00133   typedef typename LevelSetImageType::DirectionType   OutputDirectionType;
00134   typedef typename LevelSetImageType::PointType       OutputPointType;
00135 
00136   class AxisNodeType:public NodeType
00137   {
00138 public:
00139     int GetAxis() const { return m_Axis; }
00140     void SetAxis(int axis) { m_Axis = axis; }
00141     const AxisNodeType & operator=(const NodeType & node)
00142     { this->NodeType::operator=(node); return *this; }
00143 private:
00144     int m_Axis;
00145   };
00146 
00148   typedef TSpeedImage SpeedImageType;
00149 
00151   typedef typename SpeedImageType::Pointer      SpeedImagePointer;
00152   typedef typename SpeedImageType::ConstPointer SpeedImageConstPointer;
00153 
00155   itkStaticConstMacro(SetDimension, unsigned int,
00156                       LevelSetType::SetDimension);
00157   itkStaticConstMacro(SpeedImageDimension, unsigned int,
00158                       SpeedImageType::ImageDimension);
00160 
00162   typedef Index< itkGetStaticConstMacro(SetDimension) > IndexType;
00163 
00168   enum LabelType { FarPoint = 0, AlivePoint,
00169                    TrialPoint, InitialTrialPoint, OutsidePoint };
00170 
00172   typedef Image< unsigned char, itkGetStaticConstMacro(SetDimension) > LabelImageType;
00173 
00175   typedef typename LabelImageType::Pointer LabelImagePointer;
00176 
00177   template< typename TPixel >
00178   void SetBinaryMask( Image< TPixel, SetDimension >* iImage )
00179     {
00180     typedef Image< TPixel, SetDimension > InternalImageType;
00181     typedef ImageRegionConstIteratorWithIndex< InternalImageType >
00182         InternalRegionIterator;
00183     InternalRegionIterator b_it( iImage, iImage->GetLargestPossibleRegion() );
00184     b_it.GoToBegin();
00185 
00186     TPixel zero_value = NumericTraits< TPixel >::Zero;
00187     size_t NumberOfPoints = 0;
00188 
00189     NodeType node;
00190     node.SetValue( 0. );
00191 
00192     while( !b_it.IsAtEnd() )
00193       {
00194       if( b_it.Get() == zero_value )
00195         {
00196         if( NumberOfPoints == 0 )
00197           {
00198           m_OutsidePoints = NodeContainer::New();
00199           }
00200         node.SetIndex( b_it.GetIndex() );
00201         m_OutsidePoints->InsertElement( NumberOfPoints++, node );
00202 
00203         }
00204       ++b_it;
00205       }
00206     this->Modified();
00207     }
00208 
00210   void SetOutsidePoints(NodeContainer *points)
00211   {
00212     m_OutsidePoints = points;
00213     this->Modified();
00214   }
00216 
00219   void SetAlivePoints(NodeContainer *points)
00220   {
00221     m_AlivePoints = points;
00222     this->Modified();
00223   }
00225 
00227   NodeContainerPointer GetAlivePoints()
00228   {
00229     return m_AlivePoints;
00230   }
00231 
00234   void SetTrialPoints(NodeContainer *points)
00235   {
00236     m_TrialPoints = points;
00237     this->Modified();
00238   }
00240 
00242   NodeContainerPointer GetTrialPoints()
00243   {
00244     return m_TrialPoints;
00245   }
00246 
00248   LabelImagePointer GetLabelImage() const
00249   {
00250     return m_LabelImage;
00251   }
00252 
00256   void SetSpeedConstant(double value)
00257   {
00258     m_SpeedConstant = value;
00259     m_InverseSpeed = -1.0 * vnl_math_sqr(1.0 / m_SpeedConstant);
00260     this->Modified();
00261   }
00263 
00265   itkGetConstReferenceMacro(SpeedConstant, double);
00266 
00271   itkSetMacro(NormalizationFactor, double);
00272   itkGetConstMacro(NormalizationFactor, double);
00274 
00278   itkSetMacro(StoppingValue, double);
00279 
00281   itkGetConstReferenceMacro(StoppingValue, double);
00282 
00287   itkSetMacro(CollectPoints, bool);
00288 
00290   itkGetConstReferenceMacro(CollectPoints, bool);
00291   itkBooleanMacro(CollectPoints);
00293 
00298   NodeContainerPointer GetProcessedPoints() const
00299   {
00300     return m_ProcessedPoints;
00301   }
00302 
00309   virtual void SetOutputSize(const OutputSizeType & size)
00310   { m_OutputRegion = size; }
00311   virtual OutputSizeType GetOutputSize() const
00312   { return m_OutputRegion.GetSize(); }
00313   itkSetMacro(OutputRegion, OutputRegionType);
00314   itkGetConstReferenceMacro(OutputRegion, OutputRegionType);
00315   itkSetMacro(OutputSpacing, OutputSpacingType);
00316   itkGetConstReferenceMacro(OutputSpacing, OutputSpacingType);
00317   itkSetMacro(OutputDirection, OutputDirectionType);
00318   itkGetConstReferenceMacro(OutputDirection, OutputDirectionType);
00319   itkSetMacro(OutputOrigin, OutputPointType);
00320   itkGetConstReferenceMacro(OutputOrigin, OutputPointType);
00321   itkSetMacro(OverrideOutputInformation, bool);
00322   itkGetConstReferenceMacro(OverrideOutputInformation, bool);
00323   itkBooleanMacro(OverrideOutputInformation);
00325 
00326 #ifdef ITK_USE_CONCEPT_CHECKING
00327 
00328   itkConceptMacro( SameDimensionCheck,
00329                    ( Concept::SameDimension< SetDimension, SpeedImageDimension > ) );
00330   itkConceptMacro( SpeedConvertibleToDoubleCheck,
00331                    ( Concept::Convertible< typename TSpeedImage::PixelType, double > ) );
00332   itkConceptMacro( DoubleConvertibleToLevelSetCheck,
00333                    ( Concept::Convertible< double, PixelType > ) );
00334   itkConceptMacro( LevelSetOStreamWritableCheck,
00335                    ( Concept::OStreamWritable< PixelType > ) );
00336 
00338 #endif
00339 protected:
00340   FastMarchingImageFilter();
00341   ~FastMarchingImageFilter(){}
00342   void PrintSelf(std::ostream & os, Indent indent) const;
00344 
00345   virtual void Initialize(LevelSetImageType *);
00346 
00347   virtual void UpdateNeighbors(const IndexType & index,
00348                                const SpeedImageType *, LevelSetImageType *);
00349 
00350   virtual double UpdateValue(const IndexType & index,
00351                              const SpeedImageType *, LevelSetImageType *);
00352 
00353   const AxisNodeType & GetNodeUsedInCalculation(unsigned int idx) const
00354   { return m_NodesUsed[idx]; }
00355 
00356   void GenerateData();
00357 
00359   virtual void GenerateOutputInformation();
00360 
00361   virtual void EnlargeOutputRequestedRegion(DataObject *output);
00362 
00367   itkGetConstReferenceMacro(LargeValue, PixelType);
00368 
00369   OutputRegionType m_BufferedRegion;
00370   typedef typename LevelSetImageType::IndexType LevelSetIndexType;
00371   LevelSetIndexType m_StartIndex;
00372   LevelSetIndexType m_LastIndex;
00373 
00374   itkGetConstReferenceMacro(StartIndex, LevelSetIndexType);
00375   itkGetConstReferenceMacro(LastIndex, LevelSetIndexType);
00376 private:
00377   FastMarchingImageFilter(const Self &); //purposely not implemented
00378   void operator=(const Self &);          //purposely not implemented
00379 
00380   NodeContainerPointer m_AlivePoints;
00381   NodeContainerPointer m_TrialPoints;
00382   NodeContainerPointer m_OutsidePoints;
00383 
00384   LabelImagePointer m_LabelImage;
00385 
00386   double m_SpeedConstant;
00387   double m_InverseSpeed;
00388   double m_StoppingValue;
00389 
00390   bool                 m_CollectPoints;
00391   NodeContainerPointer m_ProcessedPoints;
00392 
00393   OutputRegionType    m_OutputRegion;
00394   OutputPointType     m_OutputOrigin;
00395   OutputSpacingType   m_OutputSpacing;
00396   OutputDirectionType m_OutputDirection;
00397   bool                m_OverrideOutputInformation;
00398 
00399   typename LevelSetImageType::PixelType m_LargeValue;
00400   AxisNodeType m_NodesUsed[SetDimension];
00401 
00405   typedef std::vector< AxisNodeType >  HeapContainer;
00406   typedef std::greater< AxisNodeType > NodeComparer;
00407   typedef std::priority_queue< AxisNodeType, HeapContainer, NodeComparer >
00408   HeapType;
00409 
00410   HeapType m_TrialHeap;
00411 
00412   double m_NormalizationFactor;
00413 };
00414 } // namespace itk
00415 
00416 #ifndef ITK_MANUAL_INSTANTIATION
00417 #include "itkFastMarchingImageFilter.hxx"
00418 #endif
00419 
00420 #endif
00421