ITK  4.1.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 
00397   virtual void OverrideBoundaryCondition(const
00398                                          ImageBoundaryConditionPointerType i)
00399   { m_BoundaryCondition = i; }
00400 
00403   virtual void ResetBoundaryCondition()
00404   { m_BoundaryCondition = &m_InternalBoundaryCondition;  }
00405 
00407   void SetBoundaryCondition(const TBoundaryCondition & c)
00408   { m_InternalBoundaryCondition = c; }
00409 
00411   ImageBoundaryConditionPointerType GetBoundaryCondition() const
00412   { return m_BoundaryCondition; }
00413 
00415   void NeedToUseBoundaryConditionOn()
00416   {
00417     this->SetNeedToUseBoundaryCondition(true);
00418   }
00419 
00420   void NeedToUseBoundaryConditionOff()
00421   {
00422     this->SetNeedToUseBoundaryCondition(false);
00423   }
00424 
00425   void SetNeedToUseBoundaryCondition(bool b)
00426   {
00427     m_NeedToUseBoundaryCondition = b;
00428   }
00429 
00430   bool GetNeedToUseBoundaryCondition() const
00431   {
00432     return m_NeedToUseBoundaryCondition;
00433   }
00434 
00435 protected:
00436 
00439   virtual void SetLoop(const IndexType & p)
00440   {  m_Loop = p; m_IsInBoundsValid = false; }
00441 
00445   virtual void SetBound(const SizeType &);
00446 
00451   virtual void SetPixelPointers(const IndexType &);
00452 
00455   virtual void SetBeginIndex(const IndexType & start)
00456   {  m_BeginIndex = start;  }
00457 
00460   virtual void SetEndIndex();
00461 
00464   IndexType m_BeginIndex;
00465 
00467   IndexType m_Bound;
00468 
00470   const InternalPixelType *m_Begin;
00471 
00473   typename ImageType::ConstWeakPointer m_ConstImage;
00474 
00476   const InternalPixelType *m_End;
00477 
00480   IndexType m_EndIndex;
00481 
00483   IndexType m_Loop;
00484 
00486   RegionType m_Region;
00487 
00493   OffsetType m_WrapOffset;
00494 
00499   ImageBoundaryConditionPointerType m_BoundaryCondition;
00500 
00503   mutable bool m_InBounds[Dimension];
00504 
00506   mutable bool m_IsInBounds;
00507 
00511   mutable bool m_IsInBoundsValid;
00512 
00514   IndexType m_InnerBoundsLow;
00515 
00517   IndexType m_InnerBoundsHigh;
00518 
00520   TBoundaryCondition m_InternalBoundaryCondition;
00521 
00523   bool m_NeedToUseBoundaryCondition;
00524 
00526   NeighborhoodAccessorFunctorType m_NeighborhoodAccessorFunctor;
00527 };
00528 
00529 template< class TImage >
00530 inline ConstNeighborhoodIterator< TImage >
00531 operator+(const ConstNeighborhoodIterator< TImage > & it,
00532           const typename ConstNeighborhoodIterator< TImage >
00533           ::OffsetType & ind)
00534 {
00535   ConstNeighborhoodIterator< TImage > ret;
00536   ret = it;
00537   ret += ind;
00538   return ret;
00539 }
00540 
00541 template< class TImage >
00542 inline ConstNeighborhoodIterator< TImage >
00543 operator+(const typename ConstNeighborhoodIterator< TImage >
00544           ::OffsetType & ind,
00545           const ConstNeighborhoodIterator< TImage > & it)
00546 {  return ( it + ind ); }
00547 
00548 template< class TImage >
00549 inline ConstNeighborhoodIterator< TImage >
00550 operator-(const ConstNeighborhoodIterator< TImage > & it,
00551           const typename ConstNeighborhoodIterator< TImage >
00552           ::OffsetType & ind)
00553 {
00554   ConstNeighborhoodIterator< TImage > ret;
00555   ret = it;
00556   ret -= ind;
00557   return ret;
00558 }
00559 } // namespace itk
00560 
00561 // Define instantiation macro for this template.
00562 #define ITK_TEMPLATE_ConstNeighborhoodIterator(_, EXPORT, TypeX, TypeY)     \
00563   namespace itk                                                             \
00564   {                                                                         \
00565   _( 2 ( class EXPORT ConstNeighborhoodIterator< ITK_TEMPLATE_2 TypeX > ) ) \
00566   namespace Templates                                                       \
00567   {                                                                         \
00568   typedef ConstNeighborhoodIterator< ITK_TEMPLATE_2 TypeX >                 \
00569   ConstNeighborhoodIterator##TypeY;                                       \
00570   }                                                                         \
00571   }
00572 
00573 #if ITK_TEMPLATE_EXPLICIT
00574 #include "Templates/itkConstNeighborhoodIterator+-.h"
00575 #endif
00576 
00577 #if ITK_TEMPLATE_TXX
00578 #include "itkConstNeighborhoodIterator.hxx"
00579 #endif
00580 
00581 /*
00582 #ifndef ITK_MANUAL_INSTANTIATION
00583 #include "itkConstNeighborhoodIterator.hxx"
00584 #endif
00585 */
00586 #endif
00587