00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkConstNeighborhoodIterator_h
00018 #define __itkConstNeighborhoodIterator_h
00019
00020 #include <vector>
00021 #include <string.h>
00022 #include <iostream>
00023 #include "itkImage.h"
00024 #include "itkIndex.h"
00025 #include "itkOffset.h"
00026 #include "itkSize.h"
00027 #include "itkImageRegion.h"
00028 #include "itkMacro.h"
00029 #include "itkNeighborhood.h"
00030 #include "itkImageBoundaryCondition.h"
00031 #include "itkExceptionObject.h"
00032 #include "itkZeroFluxNeumannBoundaryCondition.h"
00033
00034 namespace itk {
00035
00050 template<class TImage, class TBoundaryCondition
00051 = ZeroFluxNeumannBoundaryCondition<TImage> >
00052 class ITK_EXPORT ConstNeighborhoodIterator
00053 : public Neighborhood<ITK_TYPENAME TImage::InternalPixelType *,
00054 ::itk::GetImageDimension<TImage>::ImageDimension>
00055 {
00056 public:
00058 typedef typename TImage::InternalPixelType InternalPixelType;
00059 typedef typename TImage::PixelType PixelType;
00060
00062 itkStaticConstMacro(Dimension, unsigned int, TImage::ImageDimension);
00063
00065 typedef ConstNeighborhoodIterator Self;
00066 typedef Neighborhood<InternalPixelType *, itkGetStaticConstMacro(Dimension)> Superclass;
00067
00069 typedef typename Superclass::OffsetType OffsetType;
00070 typedef typename OffsetType::OffsetValueType OffsetValueType;
00071 typedef typename Superclass::RadiusType RadiusType;
00072 typedef typename Superclass::SizeType SizeType;
00073 typedef typename Superclass::SizeValueType SizeValueType;
00074 typedef typename Superclass::Iterator Iterator;
00075 typedef typename Superclass::ConstIterator ConstIterator;
00076
00078 typedef TImage ImageType;
00079 typedef typename TImage::RegionType RegionType;
00080 typedef Index<itkGetStaticConstMacro(Dimension)> IndexType;
00081 typedef typename IndexType::IndexValueType IndexValueType;
00082 typedef Neighborhood<PixelType, itkGetStaticConstMacro(Dimension)> NeighborhoodType;
00083
00087 typedef typename ImageType::NeighborhoodAccessorFunctorType NeighborhoodAccessorFunctorType;
00088
00090 typedef TBoundaryCondition BoundaryConditionType;
00091
00093 typedef ImageBoundaryCondition<ImageType> *ImageBoundaryConditionPointerType;
00094 typedef ImageBoundaryCondition<ImageType> const *ImageBoundaryConditionConstPointerType;
00095
00097 ConstNeighborhoodIterator();
00098
00100 virtual ~ConstNeighborhoodIterator() {}
00101
00103 ConstNeighborhoodIterator( const ConstNeighborhoodIterator & );
00104
00107 ConstNeighborhoodIterator(const SizeType &radius,
00108 const ImageType * ptr,
00109 const RegionType ®ion
00110 )
00111 {
00112 this->Initialize(radius, ptr, region);
00113 for (unsigned int i=0; i < Dimension; i++)
00114 { m_InBounds[i] = false; }
00115 this->ResetBoundaryCondition();
00116 m_NeighborhoodAccessorFunctor = ptr->GetNeighborhoodAccessor();
00117 m_NeighborhoodAccessorFunctor.SetBegin( ptr->GetBufferPointer() );
00118 }
00119
00121 Self &operator=(const Self& orig);
00122
00124 virtual void PrintSelf(std::ostream &, Indent) const;
00125
00128 OffsetType ComputeInternalIndex(unsigned int n) const;
00129
00131 IndexType GetBound() const
00132 { return m_Bound; }
00133
00136 long GetBound(unsigned int n) const
00137 { return m_Bound[n]; }
00138
00140 const InternalPixelType *GetCenterPointer() const
00141 { return (this->operator[]((this->Size())>>1)); }
00142
00144 PixelType GetCenterPixel() const
00145 { return m_NeighborhoodAccessorFunctor.Get( this->GetCenterPointer() ); }
00146
00148 const ImageType * GetImagePointer(void) const
00149 { return m_ConstImage; }
00150
00153 virtual IndexType GetIndex(void) const
00154 { return m_Loop; }
00155
00158 virtual NeighborhoodType GetNeighborhood() const;
00159
00161 virtual PixelType GetPixel(const unsigned i) const
00162 {
00163 if( !m_NeedToUseBoundaryCondition )
00164 {
00165 return ( m_NeighborhoodAccessorFunctor.Get( this->operator[]( i ) ) );
00166 }
00167 bool inbounds;
00168 return this->GetPixel( i, inbounds );
00169 }
00170
00176 virtual PixelType GetPixel(const unsigned i, bool& IsInBounds) const;
00177
00180 virtual PixelType GetPixel(const OffsetType &o) const
00181 { bool inbounds; return (this->GetPixel(this->GetNeighborhoodIndex(o), inbounds)); }
00182
00188 virtual PixelType GetPixel(const OffsetType &o,
00189 bool& IsInBounds) const
00190 { return (this->GetPixel(this->GetNeighborhoodIndex(o), IsInBounds)); }
00191
00195 virtual PixelType GetNext(const unsigned axis, const unsigned i) const
00196 { return (this->GetPixel(this->GetCenterNeighborhoodIndex()
00197 + (i * this->GetStride(axis)))); }
00198
00202 virtual PixelType GetNext(const unsigned axis) const
00203 { return (this->GetPixel(this->GetCenterNeighborhoodIndex()
00204 + this->GetStride(axis))); }
00205
00209 virtual PixelType GetPrevious(const unsigned axis, const unsigned i) const
00210 { return (this->GetPixel(this->GetCenterNeighborhoodIndex()
00211 - (i * this->GetStride(axis)))); }
00212
00216 virtual PixelType GetPrevious(const unsigned axis) const
00217 { return (this->GetPixel(this->GetCenterNeighborhoodIndex()
00218 - this->GetStride(axis))); }
00219
00222 virtual IndexType GetIndex(const OffsetType &o) const
00223 { return (this->GetIndex() + o); }
00224
00227 virtual IndexType GetIndex(const unsigned i) const
00228 { return (this->GetIndex() + this->GetOffset(i)); }
00229
00231 RegionType GetRegion() const
00232 { return m_Region; }
00233
00236 IndexType GetBeginIndex() const
00237 { return m_BeginIndex; }
00238
00241 RegionType GetBoundingBoxAsImageRegion() const;
00242
00244 OffsetType GetWrapOffset() const
00245 { return m_WrapOffset; }
00246
00252 OffsetValueType GetWrapOffset(unsigned int n) const
00253 { return m_WrapOffset[n]; }
00254
00258 virtual void GoToBegin();
00259
00262 virtual void GoToEnd();
00263
00266 virtual void Initialize(const SizeType &radius, const ImageType *ptr,
00267 const RegionType ®ion);
00268
00271 virtual bool IsAtBegin() const
00272 { return ( this->GetCenterPointer() == m_Begin ); }
00273
00276 virtual bool IsAtEnd() const
00277 {
00278 if ( this->GetCenterPointer() > m_End )
00279 {
00280 ExceptionObject e(__FILE__, __LINE__);
00281 OStringStream msg;
00282 msg << "In method IsAtEnd, CenterPointer = " << this->GetCenterPointer()
00283 << " is greater than End = " << m_End
00284 << std::endl
00285 << " " << *this;
00286 e.SetDescription(msg.str().c_str());
00287 throw e;
00288 }
00289 return ( this->GetCenterPointer() == m_End );
00290 }
00291
00296 Self &operator++();
00297
00302 Self &operator--();
00303
00307 bool operator==(const Self &it) const
00308 { return it.GetCenterPointer() == this->GetCenterPointer(); }
00309
00313 bool operator!=(const Self &it) const
00314 { return it.GetCenterPointer() != this->GetCenterPointer(); }
00315
00319 bool operator<(const Self &it) const
00320 { return this->GetCenterPointer() < it.GetCenterPointer(); }
00321
00325 bool operator<=(const Self &it) const
00326 { return this->GetCenterPointer() <= it.GetCenterPointer(); }
00327
00331 bool operator>(const Self &it) const
00332 { return this->GetCenterPointer() > it.GetCenterPointer(); }
00333
00337 bool operator>=(const Self &it) const
00338 { return this->GetCenterPointer() >= it.GetCenterPointer(); }
00339
00344 void SetLocation( const IndexType& position )
00345 {
00346 this->SetLoop(position);
00347 this->SetPixelPointers(position);
00348 }
00349
00350
00354 Self &operator+=(const OffsetType &);
00355
00359 Self &operator-=(const OffsetType &);
00360
00362 OffsetType operator-(const Self& b)
00363 { return m_Loop - b.m_Loop; }
00364
00368 bool InBounds() const;
00369
00375 virtual void OverrideBoundaryCondition(const ImageBoundaryConditionPointerType i)
00376 { m_BoundaryCondition = i; }
00377
00380 virtual void ResetBoundaryCondition()
00381 { m_BoundaryCondition = &m_InternalBoundaryCondition; }
00382
00384 void SetBoundaryCondition( const TBoundaryCondition &c )
00385 { m_InternalBoundaryCondition = c; }
00386
00388 const BoundaryConditionType *GetBoundaryCondition() const
00389 { return dynamic_cast<BoundaryConditionType *>(m_BoundaryCondition); }
00390
00392 void NeedToUseBoundaryConditionOn()
00393 {
00394 this->SetNeedToUseBoundaryCondition(true);
00395 }
00396 void NeedToUseBoundaryConditionOff()
00397 {
00398 this->SetNeedToUseBoundaryCondition(false);
00399 }
00400 void SetNeedToUseBoundaryCondition(bool b)
00401 {
00402 m_NeedToUseBoundaryCondition = b;
00403 }
00404 bool GetNeedToUseBoundaryCondition() const
00405 {
00406 return m_NeedToUseBoundaryCondition;
00407 }
00408
00409
00410 protected:
00411
00414 virtual void SetLoop( const IndexType& p )
00415 { m_Loop = p; m_IsInBoundsValid = false;}
00416
00420 virtual void SetBound(const SizeType &);
00421
00426 virtual void SetPixelPointers(const IndexType &);
00427
00430 virtual void SetBeginIndex( const IndexType& start)
00431 { m_BeginIndex = start; }
00432
00435 virtual void SetEndIndex();
00436
00439 IndexType m_BeginIndex;
00440
00442 IndexType m_Bound;
00443
00445 const InternalPixelType *m_Begin;
00446
00448 typename ImageType::ConstWeakPointer m_ConstImage;
00449
00450
00451
00452
00453 const InternalPixelType *m_End;
00454
00457 IndexType m_EndIndex;
00458
00460 IndexType m_Loop;
00461
00463 RegionType m_Region;
00464
00469 OffsetType m_WrapOffset;
00470
00475 ImageBoundaryConditionPointerType m_BoundaryCondition;
00476
00479 mutable bool m_InBounds[Dimension];
00480
00482 mutable bool m_IsInBounds;
00483
00487 mutable bool m_IsInBoundsValid;
00488
00490 IndexType m_InnerBoundsLow;
00491
00493 IndexType m_InnerBoundsHigh;
00494
00496 TBoundaryCondition m_InternalBoundaryCondition;
00497
00499 bool m_NeedToUseBoundaryCondition;
00500
00502 NeighborhoodAccessorFunctorType m_NeighborhoodAccessorFunctor;
00503
00504 };
00505
00506 template<class TImage>
00507 inline ConstNeighborhoodIterator<TImage>
00508 operator+(const ConstNeighborhoodIterator<TImage> &it,
00509 const typename ConstNeighborhoodIterator<TImage>
00510 ::OffsetType &ind)
00511 {
00512 ConstNeighborhoodIterator<TImage> ret;
00513 ret = it;
00514 ret += ind;
00515 return ret;
00516 }
00517
00518 template<class TImage>
00519 inline ConstNeighborhoodIterator<TImage>
00520 operator+(const typename ConstNeighborhoodIterator<TImage>
00521 ::OffsetType &ind,
00522 const ConstNeighborhoodIterator<TImage> &it)
00523 { return (it + ind); }
00524
00525 template<class TImage>
00526 inline ConstNeighborhoodIterator<TImage>
00527 operator-(const ConstNeighborhoodIterator<TImage> &it,
00528 const typename ConstNeighborhoodIterator<TImage>
00529 ::OffsetType &ind)
00530 {
00531 ConstNeighborhoodIterator<TImage> ret;
00532 ret = it;
00533 ret -= ind;
00534 return ret;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 }
00550
00551
00552 #ifndef ITK_MANUAL_INSTANTIATION
00553 #include "itkConstNeighborhoodIterator.txx"
00554 #endif
00555
00556 #endif