ITK  4.2.0
Insight Segmentation and Registration Toolkit
itkConstNeighborhoodIterator.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 __itkConstNeighborhoodIterator_h
00019 #define __itkConstNeighborhoodIterator_h
00020 
00021 #include <vector>
00022 #include <string.h>
00023 #include <iostream>
00024 #include "itkImage.h"
00025 #include "itkNeighborhood.h"
00026 #include "itkMacro.h"
00027 #include "itkZeroFluxNeumannBoundaryCondition.h"
00028 
00029 namespace itk
00030 {
00049 template< class TImage,  class TBoundaryCondition =
00050             ZeroFluxNeumannBoundaryCondition< TImage > >
00051 class ITK_EXPORT ConstNeighborhoodIterator:
00052   public Neighborhood< typename TImage::InternalPixelType *,
00053                        TImage::ImageDimension >
00054 {
00055 public:
00057   typedef typename TImage::InternalPixelType InternalPixelType;
00058   typedef typename TImage::PixelType         PixelType;
00059 
00061   itkStaticConstMacro(Dimension, unsigned int, TImage::ImageDimension);
00062 
00064   typedef unsigned int                  DimensionValueType;
00065 
00067   typedef ConstNeighborhoodIterator Self;
00068   typedef Neighborhood< InternalPixelType *,
00069                         itkGetStaticConstMacro(Dimension) >    Superclass;
00070 
00072   typedef typename Superclass::OffsetType      OffsetType;
00073   typedef typename Superclass::RadiusType      RadiusType;
00074   typedef typename Superclass::SizeType        SizeType;
00075   typedef typename Superclass::Iterator        Iterator;
00076   typedef typename Superclass::ConstIterator   ConstIterator;
00077 
00079   typedef TImage                                     ImageType;
00080   typedef typename TImage::RegionType                RegionType;
00081   typedef Index< itkGetStaticConstMacro(Dimension) > IndexType;
00082   typedef Neighborhood< PixelType, itkGetStaticConstMacro(Dimension) >
00083   NeighborhoodType;
00085 
00087   typedef typename NeighborhoodType::NeighborIndexType  NeighborIndexType;
00088 
00092   typedef typename ImageType::NeighborhoodAccessorFunctorType
00093   NeighborhoodAccessorFunctorType;
00094 
00096   typedef TBoundaryCondition BoundaryConditionType;
00097 
00099   typedef ImageBoundaryCondition< ImageType > *ImageBoundaryConditionPointerType;
00100   typedef ImageBoundaryCondition< ImageType > const *
00101   ImageBoundaryConditionConstPointerType;
00102 
00104   ConstNeighborhoodIterator();
00105 
00107   virtual ~ConstNeighborhoodIterator() {}
00108 
00110   ConstNeighborhoodIterator(const ConstNeighborhoodIterator &);
00111 
00114   ConstNeighborhoodIterator(const SizeType & radius,
00115                             const ImageType *ptr,
00116                             const RegionType & region)
00117   {
00118     this->Initialize(radius, ptr, region);
00119     for ( unsigned int i = 0; i < Dimension; i++ )
00120               { m_InBounds[i] = false; }
00121     this->ResetBoundaryCondition();
00122     m_NeighborhoodAccessorFunctor = ptr->GetNeighborhoodAccessor();
00123     m_NeighborhoodAccessorFunctor.SetBegin( ptr->GetBufferPointer() );
00124   }
00126 
00128   Self & operator=(const Self & orig);
00129 
00131   virtual void PrintSelf(std::ostream &, Indent) const;
00132 
00135   OffsetType ComputeInternalIndex(NeighborIndexType n) const;
00136 
00138   IndexType GetBound() const
00139   {    return m_Bound;   }
00140 
00143   IndexValueType GetBound(NeighborIndexType n) const
00144   {    return m_Bound[n];  }
00145 
00147   const InternalPixelType * GetCenterPointer() const
00148   {    return ( this->operator[]( ( this->Size() ) >> 1 ) );  }
00149 
00152   PixelType GetCenterPixel() const
00153   { return m_NeighborhoodAccessorFunctor.Get( this->GetCenterPointer() ); }
00154 
00156   const ImageType * GetImagePointer(void) const
00157   { return m_ConstImage; }
00158 
00161   virtual IndexType GetIndex(void) const
00162   { return m_Loop;  }
00163 
00166   virtual NeighborhoodType GetNeighborhood() const;
00167 
00169   virtual PixelType GetPixel(NeighborIndexType i) const
00170   {
00171     if ( !m_NeedToUseBoundaryCondition )
00172       {
00173       return ( m_NeighborhoodAccessorFunctor.Get( this->operator[](i) ) );
00174       }
00175     bool inbounds;
00176     return this->GetPixel(i, inbounds);
00177   }
00179 
00185   virtual PixelType GetPixel(NeighborIndexType i, bool & IsInBounds) const;
00186 
00189   virtual PixelType GetPixel(const OffsetType & o) const
00190   {
00191     bool inbounds;
00192 
00193     return ( this->GetPixel(this->GetNeighborhoodIndex(o), inbounds) );
00194   }
00195 
00201   virtual PixelType GetPixel(const OffsetType & o,
00202                              bool & IsInBounds) const
00203   { return ( this->GetPixel(this->GetNeighborhoodIndex(o), IsInBounds) ); }
00204 
00208   virtual PixelType GetNext(const unsigned axis, NeighborIndexType i) const
00209   {
00210     return ( this->GetPixel( this->GetCenterNeighborhoodIndex()
00211                              + ( i * this->GetStride(axis) ) ) );
00212   }
00213 
00217   virtual PixelType GetNext(const unsigned axis) const
00218   {
00219     return ( this->GetPixel( this->GetCenterNeighborhoodIndex()
00220                              + this->GetStride(axis) ) );
00221   }
00222 
00226   virtual PixelType GetPrevious(const unsigned axis, NeighborIndexType i) const
00227   {
00228     return ( this->GetPixel( this->GetCenterNeighborhoodIndex()
00229                              - ( i * this->GetStride(axis) ) ) );
00230   }
00231 
00235   virtual PixelType GetPrevious(const unsigned axis) const
00236   {
00237     return ( this->GetPixel( this->GetCenterNeighborhoodIndex()
00238                              - this->GetStride(axis) ) );
00239   }
00240 
00243   virtual IndexType GetIndex(const OffsetType & o) const
00244   { return ( this->GetIndex() + o ); }
00245 
00248   virtual IndexType GetIndex(NeighborIndexType i) const
00249   { return ( this->GetIndex() + this->GetOffset(i) ); }
00250 
00252   RegionType GetRegion() const
00253   { return m_Region; }
00254 
00257   IndexType GetBeginIndex() const
00258   { return m_BeginIndex; }
00259 
00262   RegionType GetBoundingBoxAsImageRegion() const;
00263 
00265   OffsetType GetWrapOffset() const
00266   {  return m_WrapOffset;  }
00267 
00273   OffsetValueType GetWrapOffset(NeighborIndexType n) const
00274   {    return m_WrapOffset[n];   }
00275 
00279   virtual void GoToBegin();
00280 
00283   virtual void GoToEnd();
00284 
00287   virtual void Initialize(const SizeType & radius, const ImageType *ptr,
00288                           const RegionType & region);
00289 
00292   virtual bool IsAtBegin() const
00293   {    return ( this->GetCenterPointer() == m_Begin );   }
00294 
00297   virtual bool IsAtEnd() const
00298   {
00299     if ( this->GetCenterPointer() > m_End )
00300       {
00301       ExceptionObject    e(__FILE__, __LINE__);
00302       std::ostringstream msg;
00303       msg << "In method IsAtEnd, CenterPointer = " << this->GetCenterPointer()
00304           << " is greater than End = " << m_End
00305           << std::endl
00306           << "  " << *this;
00307       e.SetDescription( msg.str().c_str() );
00308       throw e;
00309       }
00310     return ( this->GetCenterPointer() == m_End );
00311   }
00313 
00318   Self & operator++();
00319 
00324   Self & operator--();
00325 
00329   bool operator==(const Self & it) const
00330   {   return it.GetCenterPointer() == this->GetCenterPointer();   }
00331 
00335   bool operator!=(const Self & it) const
00336   {    return it.GetCenterPointer() != this->GetCenterPointer();  }
00337 
00341   bool operator<(const Self & it) const
00342   {  return this->GetCenterPointer() < it.GetCenterPointer();  }
00343 
00347   bool operator<=(const Self & it) const
00348   {    return this->GetCenterPointer() <= it.GetCenterPointer();  }
00349 
00353   bool operator>(const Self & it) const
00354   {    return this->GetCenterPointer() > it.GetCenterPointer();  }
00355 
00359   bool operator>=(const Self & it) const
00360   {    return this->GetCenterPointer() >= it.GetCenterPointer();  }
00361 
00366   void SetLocation(const IndexType & position)
00367   {
00368     this->SetLoop(position);
00369     this->SetPixelPointers(position);
00370   }
00372 
00376   Self & operator+=(const OffsetType &);
00377 
00381   Self & operator-=(const OffsetType &);
00382 
00384   OffsetType operator-(const Self & b)
00385   {  return m_Loop - b.m_Loop;  }
00386 
00390   bool InBounds() const;
00391 
00403   bool IndexInBounds(NeighborIndexType n, OffsetType & internalIndex, OffsetType & offset ) const;
00404 
00410   virtual void OverrideBoundaryCondition(const
00411                                          ImageBoundaryConditionPointerType i)
00412   { m_BoundaryCondition = i; }
00413 
00416   virtual void ResetBoundaryCondition()
00417   { m_BoundaryCondition = &m_InternalBoundaryCondition;  }
00418 
00420   void SetBoundaryCondition(const TBoundaryCondition & c)
00421   { m_InternalBoundaryCondition = c; }
00422 
00424   ImageBoundaryConditionPointerType GetBoundaryCondition() const
00425   { return m_BoundaryCondition; }
00426 
00428   void NeedToUseBoundaryConditionOn()
00429   {
00430     this->SetNeedToUseBoundaryCondition(true);
00431   }
00432 
00433   void NeedToUseBoundaryConditionOff()
00434   {
00435     this->SetNeedToUseBoundaryCondition(false);
00436   }
00437 
00438   void SetNeedToUseBoundaryCondition(bool b)
00439   {
00440     m_NeedToUseBoundaryCondition = b;
00441   }
00442 
00443   bool GetNeedToUseBoundaryCondition() const
00444   {
00445     return m_NeedToUseBoundaryCondition;
00446   }
00447 
00448 protected:
00449 
00452   virtual void SetLoop(const IndexType & p)
00453   {  m_Loop = p; m_IsInBoundsValid = false; }
00454 
00458   virtual void SetBound(const SizeType &);
00459 
00464   virtual void SetPixelPointers(const IndexType &);
00465 
00468   virtual void SetBeginIndex(const IndexType & start)
00469   {  m_BeginIndex = start;  }
00470 
00473   virtual void SetEndIndex();
00474 
00477   IndexType m_BeginIndex;
00478 
00480   IndexType m_Bound;
00481 
00483   const InternalPixelType *m_Begin;
00484 
00486   typename ImageType::ConstWeakPointer m_ConstImage;
00487 
00489   const InternalPixelType *m_End;
00490 
00493   IndexType m_EndIndex;
00494 
00496   IndexType m_Loop;
00497 
00499   RegionType m_Region;
00500 
00506   OffsetType m_WrapOffset;
00507 
00512   ImageBoundaryConditionPointerType m_BoundaryCondition;
00513 
00516   mutable bool m_InBounds[Dimension];
00517 
00519   mutable bool m_IsInBounds;
00520 
00524   mutable bool m_IsInBoundsValid;
00525 
00527   IndexType m_InnerBoundsLow;
00528 
00530   IndexType m_InnerBoundsHigh;
00531 
00533   TBoundaryCondition m_InternalBoundaryCondition;
00534 
00536   bool m_NeedToUseBoundaryCondition;
00537 
00539   NeighborhoodAccessorFunctorType m_NeighborhoodAccessorFunctor;
00540 };
00541 
00542 template< class TImage >
00543 inline ConstNeighborhoodIterator< TImage >
00544 operator+(const ConstNeighborhoodIterator< TImage > & it,
00545           const typename ConstNeighborhoodIterator< TImage >
00546           ::OffsetType & ind)
00547 {
00548   ConstNeighborhoodIterator< TImage > ret;
00549   ret = it;
00550   ret += ind;
00551   return ret;
00552 }
00553 
00554 template< class TImage >
00555 inline ConstNeighborhoodIterator< TImage >
00556 operator+(const typename ConstNeighborhoodIterator< TImage >
00557           ::OffsetType & ind,
00558           const ConstNeighborhoodIterator< TImage > & it)
00559 {  return ( it + ind ); }
00560 
00561 template< class TImage >
00562 inline ConstNeighborhoodIterator< TImage >
00563 operator-(const ConstNeighborhoodIterator< TImage > & it,
00564           const typename ConstNeighborhoodIterator< TImage >
00565           ::OffsetType & ind)
00566 {
00567   ConstNeighborhoodIterator< TImage > ret;
00568   ret = it;
00569   ret -= ind;
00570   return ret;
00571 }
00572 } // namespace itk
00573 
00574 // Define instantiation macro for this template.
00575 #define ITK_TEMPLATE_ConstNeighborhoodIterator(_, EXPORT, TypeX, TypeY)     \
00576   namespace itk                                                             \
00577   {                                                                         \
00578   _( 2 ( class EXPORT ConstNeighborhoodIterator< ITK_TEMPLATE_2 TypeX > ) ) \
00579   namespace Templates                                                       \
00580   {                                                                         \
00581   typedef ConstNeighborhoodIterator< ITK_TEMPLATE_2 TypeX >                 \
00582   ConstNeighborhoodIterator##TypeY;                                       \
00583   }                                                                         \
00584   }
00585 
00586 #if ITK_TEMPLATE_EXPLICIT
00587 #include "Templates/itkConstNeighborhoodIterator+-.h"
00588 #endif
00589 
00590 #if ITK_TEMPLATE_TXX
00591 #include "itkConstNeighborhoodIterator.hxx"
00592 #endif
00593 
00594 /*
00595 #ifndef ITK_MANUAL_INSTANTIATION
00596 #include "itkConstNeighborhoodIterator.hxx"
00597 #endif
00598 */
00599 #endif
00600