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 *,
00067 itkGetStaticConstMacro(Dimension)> Superclass;
00068
00070 typedef typename Superclass::OffsetType OffsetType;
00071 typedef typename OffsetType::OffsetValueType OffsetValueType;
00072 typedef typename Superclass::RadiusType RadiusType;
00073 typedef typename Superclass::SizeType SizeType;
00074 typedef typename Superclass::SizeValueType SizeValueType;
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 typename IndexType::IndexValueType IndexValueType;
00083 typedef Neighborhood<PixelType, itkGetStaticConstMacro(Dimension)>
00084 NeighborhoodType;
00086
00090 typedef typename ImageType::NeighborhoodAccessorFunctorType
00091 NeighborhoodAccessorFunctorType;
00092
00094 typedef TBoundaryCondition BoundaryConditionType;
00095
00097 typedef ImageBoundaryCondition<ImageType> *ImageBoundaryConditionPointerType;
00098 typedef ImageBoundaryCondition<ImageType> const *
00099 ImageBoundaryConditionConstPointerType;
00100
00102 ConstNeighborhoodIterator();
00103
00105 virtual ~ConstNeighborhoodIterator() {}
00106
00108 ConstNeighborhoodIterator( const ConstNeighborhoodIterator & );
00109
00112 ConstNeighborhoodIterator(const SizeType &radius,
00113 const ImageType * ptr,
00114 const RegionType ®ion)
00115 {
00116 this->Initialize(radius, ptr, region);
00117 for (unsigned int i=0; i < Dimension; i++)
00118 { m_InBounds[i] = false; }
00119 this->ResetBoundaryCondition();
00120 m_NeighborhoodAccessorFunctor = ptr->GetNeighborhoodAccessor();
00121 m_NeighborhoodAccessorFunctor.SetBegin( ptr->GetBufferPointer() );
00122 }
00124
00126 Self &operator=(const Self& orig);
00127
00129 virtual void PrintSelf(std::ostream &, Indent) const;
00130
00133 OffsetType ComputeInternalIndex(unsigned int n) const;
00134
00136 IndexType GetBound() const
00137 { return m_Bound; }
00138
00141 long GetBound(unsigned int n) const
00142 { return m_Bound[n]; }
00143
00145 const InternalPixelType *GetCenterPointer() const
00146 { return (this->operator[]((this->Size())>>1)); }
00147
00150 PixelType GetCenterPixel() const
00151 {return m_NeighborhoodAccessorFunctor.Get( this->GetCenterPointer() );}
00152
00154 const ImageType * GetImagePointer(void) const
00155 { return m_ConstImage; }
00156
00159 virtual IndexType GetIndex(void) const
00160 { return m_Loop; }
00161
00164 virtual NeighborhoodType GetNeighborhood() const;
00165
00167 virtual PixelType GetPixel(const unsigned i) const
00168 {
00169 if( !m_NeedToUseBoundaryCondition )
00170 {
00171 return ( m_NeighborhoodAccessorFunctor.Get( this->operator[]( i ) ) );
00172 }
00173 bool inbounds;
00174 return this->GetPixel( i, inbounds );
00175 }
00177
00183 virtual PixelType GetPixel(const unsigned i, bool& IsInBounds) const;
00184
00187 virtual PixelType GetPixel(const OffsetType &o) const
00188 {
00189 bool inbounds;
00190 return (this->GetPixel(this->GetNeighborhoodIndex(o), inbounds));
00191 }
00193
00199 virtual PixelType GetPixel(const OffsetType &o,
00200 bool& IsInBounds) const
00201 {return (this->GetPixel(this->GetNeighborhoodIndex(o), IsInBounds)); }
00202
00206 virtual PixelType GetNext(const unsigned axis, const unsigned i) const
00207 { return (this->GetPixel(this->GetCenterNeighborhoodIndex()
00208 + (i * this->GetStride(axis)))); }
00209
00213 virtual PixelType GetNext(const unsigned axis) const
00214 { return (this->GetPixel(this->GetCenterNeighborhoodIndex()
00215 + this->GetStride(axis))); }
00216
00220 virtual PixelType GetPrevious(const unsigned axis, const unsigned i) const
00221 { return (this->GetPixel(this->GetCenterNeighborhoodIndex()
00222 - (i * this->GetStride(axis)))); }
00223
00227 virtual PixelType GetPrevious(const unsigned axis) const
00228 { return (this->GetPixel(this->GetCenterNeighborhoodIndex()
00229 - this->GetStride(axis))); }
00230
00233 virtual IndexType GetIndex(const OffsetType &o) const
00234 { return (this->GetIndex() + o); }
00235
00238 virtual IndexType GetIndex(const unsigned i) const
00239 { return (this->GetIndex() + this->GetOffset(i)); }
00240
00242 RegionType GetRegion() const
00243 { return m_Region; }
00244
00247 IndexType GetBeginIndex() const
00248 { return m_BeginIndex; }
00249
00252 RegionType GetBoundingBoxAsImageRegion() const;
00253
00255 OffsetType GetWrapOffset() const
00256 { return m_WrapOffset; }
00257
00263 OffsetValueType GetWrapOffset(unsigned int n) const
00264 { return m_WrapOffset[n]; }
00265
00269 virtual void GoToBegin();
00270
00273 virtual void GoToEnd();
00274
00277 virtual void Initialize(const SizeType &radius, const ImageType *ptr,
00278 const RegionType ®ion);
00279
00282 virtual bool IsAtBegin() const
00283 { return ( this->GetCenterPointer() == m_Begin ); }
00284
00287 virtual bool IsAtEnd() const
00288 {
00289 if ( this->GetCenterPointer() > m_End )
00290 {
00291 ExceptionObject e(__FILE__, __LINE__);
00292 OStringStream msg;
00293 msg << "In method IsAtEnd, CenterPointer = " << this->GetCenterPointer()
00294 << " is greater than End = " << m_End
00295 << std::endl
00296 << " " << *this;
00297 e.SetDescription(msg.str().c_str());
00298 throw e;
00299 }
00300 return ( this->GetCenterPointer() == m_End );
00301 }
00303
00308 Self &operator++();
00309
00314 Self &operator--();
00315
00319 bool operator==(const Self &it) const
00320 { return it.GetCenterPointer() == this->GetCenterPointer(); }
00321
00325 bool operator!=(const Self &it) const
00326 { return it.GetCenterPointer() != this->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
00343 bool operator>(const Self &it) const
00344 { return this->GetCenterPointer() > it.GetCenterPointer(); }
00345
00349 bool operator>=(const Self &it) const
00350 { return this->GetCenterPointer() >= it.GetCenterPointer(); }
00351
00356 void SetLocation( const IndexType& position )
00357 {
00358 this->SetLoop(position);
00359 this->SetPixelPointers(position);
00360 }
00362
00363
00367 Self &operator+=(const OffsetType &);
00368
00372 Self &operator-=(const OffsetType &);
00373
00375 OffsetType operator-(const Self& b)
00376 { return m_Loop - b.m_Loop; }
00377
00381 bool InBounds() const;
00382
00388 virtual void OverrideBoundaryCondition(const
00389 ImageBoundaryConditionPointerType i)
00390 { m_BoundaryCondition = i; }
00391
00394 virtual void ResetBoundaryCondition()
00395 { m_BoundaryCondition = &m_InternalBoundaryCondition; }
00396
00398 void SetBoundaryCondition( const TBoundaryCondition &c )
00399 { m_InternalBoundaryCondition = c; }
00400
00402 const BoundaryConditionType *GetBoundaryCondition() const
00403 { return dynamic_cast<BoundaryConditionType *>(m_BoundaryCondition); }
00404
00406 void NeedToUseBoundaryConditionOn()
00407 {
00408 this->SetNeedToUseBoundaryCondition(true);
00409 }
00410 void NeedToUseBoundaryConditionOff()
00411 {
00412 this->SetNeedToUseBoundaryCondition(false);
00413 }
00414 void SetNeedToUseBoundaryCondition(bool b)
00415 {
00416 m_NeedToUseBoundaryCondition = b;
00417 }
00418 bool GetNeedToUseBoundaryCondition() const
00419 {
00420 return m_NeedToUseBoundaryCondition;
00421 }
00423
00424 protected:
00425
00428 virtual void SetLoop( const IndexType& p )
00429 { m_Loop = p; m_IsInBoundsValid = false;}
00430
00434 virtual void SetBound(const SizeType &);
00435
00440 virtual void SetPixelPointers(const IndexType &);
00441
00444 virtual void SetBeginIndex( const IndexType& start)
00445 { m_BeginIndex = start; }
00446
00449 virtual void SetEndIndex();
00450
00453 IndexType m_BeginIndex;
00454
00456 IndexType m_Bound;
00457
00459 const InternalPixelType *m_Begin;
00460
00462 typename ImageType::ConstWeakPointer m_ConstImage;
00463
00465 const InternalPixelType *m_End;
00466
00469 IndexType m_EndIndex;
00470
00472 IndexType m_Loop;
00473
00475 RegionType m_Region;
00476
00482 OffsetType m_WrapOffset;
00483
00488 ImageBoundaryConditionPointerType m_BoundaryCondition;
00489
00492 mutable bool m_InBounds[Dimension];
00493
00495 mutable bool m_IsInBounds;
00496
00500 mutable bool m_IsInBoundsValid;
00501
00503 IndexType m_InnerBoundsLow;
00504
00506 IndexType m_InnerBoundsHigh;
00507
00509 TBoundaryCondition m_InternalBoundaryCondition;
00510
00512 bool m_NeedToUseBoundaryCondition;
00513
00515 NeighborhoodAccessorFunctorType m_NeighborhoodAccessorFunctor;
00516
00517 };
00518
00519 template<class TImage>
00520 inline ConstNeighborhoodIterator<TImage>
00521 operator+(const ConstNeighborhoodIterator<TImage> &it,
00522 const typename ConstNeighborhoodIterator<TImage>
00523 ::OffsetType &ind)
00524 {
00525 ConstNeighborhoodIterator<TImage> ret;
00526 ret = it;
00527 ret += ind;
00528 return ret;
00529 }
00530
00531 template<class TImage>
00532 inline ConstNeighborhoodIterator<TImage>
00533 operator+(const typename ConstNeighborhoodIterator<TImage>
00534 ::OffsetType &ind,
00535 const ConstNeighborhoodIterator<TImage> &it)
00536 { return (it + ind); }
00537
00538 template<class TImage>
00539 inline ConstNeighborhoodIterator<TImage>
00540 operator-(const ConstNeighborhoodIterator<TImage> &it,
00541 const typename ConstNeighborhoodIterator<TImage>
00542 ::OffsetType &ind)
00543 {
00544 ConstNeighborhoodIterator<TImage> ret;
00545 ret = it;
00546 ret -= ind;
00547 return ret;
00548 }
00549
00550 }
00551
00552
00553 #define ITK_TEMPLATE_ConstNeighborhoodIterator(_, EXPORT, x, y) namespace itk { \
00554 _(2(class EXPORT ConstNeighborhoodIterator< ITK_TEMPLATE_2 x >)) \
00555 namespace Templates { typedef ConstNeighborhoodIterator< ITK_TEMPLATE_2 x > \
00556 ConstNeighborhoodIterator##y; } \
00557 }
00558
00559 #if ITK_TEMPLATE_EXPLICIT
00560 # include "Templates/itkConstNeighborhoodIterator+-.h"
00561 #endif
00562
00563 #if ITK_TEMPLATE_TXX
00564 # include "itkConstNeighborhoodIterator.txx"
00565 #endif
00566
00567
00568
00569
00570
00571
00572 #endif
00573