KWStyle - itkConstNeighborhoodIterator.h
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkConstNeighborhoodIterator.h.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:34 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12      This software is distributed WITHOUT ANY WARRANTY; without even 
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14      PURPOSE.  See the above copyright notices for more information.
15
16 =========================================================================*/
17 #ifndef __itkConstNeighborhoodIterator_h
18 #define __itkConstNeighborhoodIterator_h
19
20 #include <vector>
21 #include <string.h>
22 #include <iostream>
23 #include "itkImage.h"
24 #include "itkIndex.h"
25 #include "itkOffset.h"
26 #include "itkSize.h"
27 #include "itkImageRegion.h"
28 #include "itkMacro.h"
29 #include "itkNeighborhood.h"
30 #include "itkImageBoundaryCondition.h"
31 #include "itkExceptionObject.h"
32 #include "itkZeroFluxNeumannBoundaryCondition.h"
33
34 namespace itk {
35
36 /** \class ConstNeighborhoodIterator
37  *
38  * \brief Const version of NeighborhoodIterator, defining iteration of a local
39  * N-dimensional neighborhood of pixels across an itk::Image.
40  *
41  * ConstNeighborhoodIterator implements the read-only methods of
42  * NeighborhoodIterator.  It serves as a base class from which other iterators
43  * are derived. See NeighborhoodIterator for more complete information.
44  *
45  *
46  * \ingroup ImageIterators
47  *
48  * \sa Neighborhood \sa ImageIterator \sa NeighborhoodIterator
49  **/
50 template<class TImage,  class TBoundaryCondition
51                        = ZeroFluxNeumannBoundaryCondition<TImage> >
52 class ITK_EXPORT ConstNeighborhoodIterator
53 IND **:  public Neighborhood<ITK_TYPENAME TImage::InternalPixelType *,
54                          ::itk::GetImageDimension<TImage>::ImageDimension>
55 {
56 public:
57   /** Extract image type information. */
58   typedef typename TImage::InternalPixelType InternalPixelType;
59 TDA   typedef typename TImage::PixelType PixelType;
60     
61   /** Save the image dimension. */
62   itkStaticConstMacro(Dimension, unsigned int, TImage::ImageDimension);
63   
64   /** Standard class typedefs. */
65   typedef ConstNeighborhoodIterator Self;
66 LEN,TDA   typedef Neighborhood<InternalPixelType *, itkGetStaticConstMacro(Dimension)> Superclass;
67
68   /** Inherit typedefs from superclass */
69   typedef typename Superclass::OffsetType OffsetType;
70 TDA   typedef typename OffsetType::OffsetValueType OffsetValueType;
71   typedef typename Superclass::RadiusType RadiusType;  
72 TDA   typedef typename Superclass::SizeType SizeType;
73 TDA   typedef typename Superclass::SizeValueType SizeValueType;
74 TDA   typedef typename Superclass::Iterator Iterator;
75 TDA   typedef typename Superclass::ConstIterator ConstIterator;
76   
77   /** Typedef support for common objects */
78   typedef TImage ImageType;
79 TDA   typedef typename TImage::RegionType RegionType;
80 TDA   typedef Index<itkGetStaticConstMacro(Dimension)> IndexType;
81 TDA   typedef typename IndexType::IndexValueType IndexValueType;
82 LEN,TDA   typedef Neighborhood<PixelType, itkGetStaticConstMacro(Dimension)> NeighborhoodType;
83
84   /** Typedef for the functor used to access neighborhoods of pixel pointers.
85    * This is obtained as a trait from the image and is different for Image
86    * and VectorImage. */
87 LEN   typedef typename ImageType::NeighborhoodAccessorFunctorType NeighborhoodAccessorFunctorType;
88
89   /** Typedef for boundary condition type. */
90   typedef TBoundaryCondition BoundaryConditionType;
91   
92   /** Typedef for generic boundary condition pointer */
93   typedef ImageBoundaryCondition<ImageType> *ImageBoundaryConditionPointerType;
94 LEN,TDA   typedef ImageBoundaryCondition<ImageType> const *ImageBoundaryConditionConstPointerType;
95
96   /** Default constructor */
97   ConstNeighborhoodIterator();
98
99   /** Virtual destructor */
100   virtual ~ConstNeighborhoodIterator() {}
101
102   /** Copy constructor */
103   ConstNeighborhoodIterator( const ConstNeighborhoodIterator & );
104
105   /** Constructor which establishes the region size, neighborhood, and image
106    * over which to walk. */
107   ConstNeighborhoodIterator(const SizeType &radius,
108                        const ImageType * ptr,
109                        const RegionType ®ion
110 IND ***********************)
111 IND **{
112     this->Initialize(radius, ptr, region);
113     for (unsigned int i=0; i < Dimension; i++)
114       { m_InBounds[i] = false; }
115     this->ResetBoundaryCondition();
116     m_NeighborhoodAccessorFunctor = ptr->GetNeighborhoodAccessor();
117     m_NeighborhoodAccessorFunctor.SetBegin( ptr->GetBufferPointer() );
118 IND **}
119
120   /** Assignment operator */
121   Self &operator=(const Self& orig);
122
123   /** Standard itk print method */
124   virtual void PrintSelf(std::ostream &, Indent) const;
125
126   /** Computes the internal, N-d offset of a pixel array position n from 
127    * (0,0, ..., 0) in the "upper-left" corner of the neighborhood. */
128   OffsetType ComputeInternalIndex(unsigned int n) const;
129
130   /** Returns the array of upper loop bounds used during iteration. */
131   IndexType GetBound() const
132     {    return m_Bound;   }
133
134   /** Returns the loop bound used to define the edge of a single
135    * dimension in the itk::Image region. */
136   long GetBound(unsigned int n) const
137     {    return m_Bound[n];  }
138   
139   /** Returns the pointer to the center pixel of the neighborhood. */
140   const InternalPixelType *GetCenterPointer() const
141     {    return (this->operator[]((this->Size())>>1));  }
142   
143 LEN   /** Returns the pixel referenced at the center of the ConstNeighborhoodIterator. */
144   PixelType GetCenterPixel() const
145 LEN     {    return m_NeighborhoodAccessorFunctor.Get( this->GetCenterPointer() );  }
146
147   /** Returns a smartpointer to the image on which this iterator operates. */
148   const ImageType * GetImagePointer(void) const
149     { return m_ConstImage; }
150  
151   /** Returns the N-dimensional index of the iterator's position in
152    * the image. */
153   virtual IndexType GetIndex(void) const
154     { return m_Loop;  }
155   
156   /** Virtual function that "dereferences" a ConstNeighborhoodIterator,
157    * returning a Neighborhood of pixel values. */
158   virtual NeighborhoodType GetNeighborhood() const;
159
160   /** Returns the pixel value located at a linear array location i. */
161   virtual PixelType GetPixel(const unsigned i) const
162     { 
163     if( !m_NeedToUseBoundaryCondition )
164       {
165       return ( m_NeighborhoodAccessorFunctor.Get( this->operator[]( i ) ) );
166       }
167     bool inbounds; 
168     return this->GetPixel( i, inbounds ); 
169     }
170
171   /** Return the pixel value located at a linear array location i.
172    * Sets "IsInBounds" to true if the location is inside the
173    * image and the pixel value returned is an actual pixel in the
174    * image. Sets "IsInBounds" to false if the location is outside the
175    * image and the pixel value returned is a boundary condition. */
176   virtual PixelType GetPixel(const unsigned i, bool& IsInBounds) const;
177
178   /** Returns the pixel value located at the itk::Offset o from the center of
179 IND ******the neighborhood. */
180   virtual PixelType GetPixel(const OffsetType &o) const
181 LEN,IND **{ bool inbounds; return (this->GetPixel(this->GetNeighborhoodIndex(o), inbounds)); }
182
183   /** Returns the pixel value located at the itk::Offset o from the center of
184    * the neighborhood. Sets "IsInBounds" to true if the offset is inside the
185    * image and the pixel value returned is an actual pixel in the
186    * image. Sets "IsInBounds" to false if the offset is outside the
187    * image and the pixel value returned is a boundary condition. */
188   virtual PixelType GetPixel(const OffsetType &o,
189                              bool& IsInBounds) const
190 IND **{ return (this->GetPixel(this->GetNeighborhoodIndex(o), IsInBounds)); }
191   
192 LEN   /** Returns the pixel value located i pixels distant from the neighborhood center in
193 IND ******the positive specified ``axis'' direction. No bounds checking is done on
194 IND ******the size of the neighborhood. */
195   virtual PixelType GetNext(const unsigned axis, const unsigned i) const
196 IND **{    return (this->GetPixel(this->GetCenterNeighborhoodIndex()
197 IND ***************************+ (i * this->GetStride(axis)))); }
198
199 LEN   /** Returns the pixel value located one pixel distant from the neighborhood center in
200 IND ******the specifed positive axis direction. No bounds checking is done on the
201 IND ******size of the neighborhood. */
202   virtual PixelType GetNext(const unsigned axis) const
203 IND **{    return (this->GetPixel(this->GetCenterNeighborhoodIndex()
204 IND ***************************+ this->GetStride(axis))); }
205
206 LEN   /** Returns the pixel value located i pixels distant from the neighborhood center in
207 IND ******the negative specified ``axis'' direction. No bounds checking is done on
208 IND ******the size of the neighborhood. */
209   virtual PixelType GetPrevious(const unsigned axis, const unsigned i) const
210 IND **{ return (this->GetPixel(this->GetCenterNeighborhoodIndex()
211 IND ***************************- (i * this->GetStride(axis)))); }
212   
213 LEN   /** Returns the pixel value located one pixel distant from the neighborhood center in
214 IND ******the specifed negative axis direction. No bounds checking is done on the
215 IND ******size of the neighborhood. */
216   virtual PixelType GetPrevious(const unsigned axis) const
217 IND **{ return (this->GetPixel(this->GetCenterNeighborhoodIndex()
218 IND ***************************- this->GetStride(axis))); } 
219   
220   /** Returns the image index for neighbor pixel at offset o from the center of
221 IND ******the neighborhood. */
222   virtual IndexType GetIndex(const OffsetType &o) const
223 IND **{ return (this->GetIndex() + o); }
224
225   /** Returns the image index for neighbor pixel at index i in the
226 IND ******neighborhood. */
227   virtual IndexType GetIndex(const unsigned i) const
228 IND **{ return (this->GetIndex() + this->GetOffset(i)); }
229   
230   /**  Returns the region of iteration. */
231   RegionType GetRegion() const
232     { return m_Region; }
233   
234   /** Returns the N-dimensional starting index of the iterator's position on
235    * the image. */
236   IndexType GetBeginIndex() const
237     { return m_BeginIndex; }
238
239   /** Returns a bounding box for the region spanned by this neighborhood
240 IND ******represented by an itk::ImageRegion */
241   RegionType GetBoundingBoxAsImageRegion() const;
242   
243   /** Returns the offsets used to wrap across dimensional boundaries. */
244   OffsetType GetWrapOffset() const
245     {  return m_WrapOffset;  }
246
247   /** Returns the internal offset associated with wrapping around a single
248    * dimension's region boundary in the itk::Image.  An offset for each
249    * dimension is necessary to shift pointers when wrapping around region
250    * edges because region memory is not necessarily contiguous within the
251    * buffer. */
252   OffsetValueType GetWrapOffset(unsigned int n) const
253     {    return m_WrapOffset[n];   }
254
255   /** Virtual method for rewinding the iterator to its beginning pixel.
256    * This is useful for writing functions which take neighborhood iterators
257    * of arbitrary type and must use virtual functions. */
258   virtual void GoToBegin();
259   
260   /** Virtual method for sending the iterator to one past the last pixel in its
261    * region. */
262   virtual void GoToEnd();
263   
264   /** Initializes the iterator to walk a particular image and a particular
265    * region of that image. */
266   virtual void Initialize(const SizeType &radius, const ImageType *ptr,
267                           const RegionType ®ion);
268
269 WCM   /** Virtual method for determining whether the the iterator is at the
270    * beginning of its iteration region. */
271   virtual bool IsAtBegin() const
272     {    return ( this->GetCenterPointer() == m_Begin );   }
273   
274 WCM   /** Virtual method for determining whether the the iterator has reached the
275    * end of its iteration region. */
276   virtual bool IsAtEnd() const
277     {
278 IND ******if ( this->GetCenterPointer() > m_End )
279 IND ********{
280 IND ********ExceptionObject e(__FILE__, __LINE__);
281 IND ********OStringStream msg;
282 IND ********msg << "In method IsAtEnd, CenterPointer = " << this->GetCenterPointer()
283 IND ************<< " is greater than End = " << m_End
284             << std::endl
285             << "  " << *this;
286         e.SetDescription(msg.str().c_str());
287         throw e;
288         }
289       return ( this->GetCenterPointer() == m_End );
290     }
291   
292   /** Increments the pointers in the ConstNeighborhoodIterator,
293    * wraps across boundaries automatically, accounting for
294    * the disparity in the buffer size and the region size of the
295    * image. */
296   Self &operator++();
297   
298   /** Decrements the pointers in the ConstNeighborhoodIterator,
299    * wraps across boundaries automatically, accounting for
300    * the disparity in the buffer size and the region size of the
301    * image. */
302   Self &operator--();  
303  
304   /** Returns a boolean == comparison of the memory addresses of the center
305    * elements of two ConstNeighborhoodIterators of like pixel type and
306    * dimensionality.  The radii of the iterators are ignored. */
307   bool operator==(const Self &it) const 
308     {   return  it.GetCenterPointer() == this->GetCenterPointer();   }
309   
310   /** Returns a boolean != comparison of the memory addresses of the center
311    * elements of two ConstNeighborhoodIterators of like pixel type and
312    * dimensionality.  The radii of the iterators are ignored. */
313   bool operator!=(const Self &it) const
314     {    return  it.GetCenterPointer() != this->GetCenterPointer();  }
315   
316   /** Returns a boolean < comparison of the memory addresses of the center
317    * elements of two ConstNeighborhoodIterators of like pixel type and
318    * dimensionality.  The radii of the iterators are ignored. */
319   bool operator<(const Self &it) const
320     {  return  this->GetCenterPointer() < it.GetCenterPointer();  }
321
322   /** Returns a boolean < comparison of the memory addresses of the center
323    * elements of two ConstNeighborhoodIterators of like pixel type and
324    * dimensionality.  The radii of the iterators are ignored. */
325   bool operator<=(const Self &it) const
326     {    return  this->GetCenterPointer() <= it.GetCenterPointer();  }
327   
328   /** Returns a boolean > comparison of the memory addresses of the center
329    * elements of two ConstNeighborhoodIterators of like pixel type and
330    * dimensionality.  The radii of the iterators are ignored. */
331   bool operator>(const Self &it) const
332     {    return  this->GetCenterPointer() > it.GetCenterPointer();  }
333
334   /** Returns a boolean >= comparison of the memory addresses of the center
335    * elements of two ConstNeighborhoodIterators of like pixel type and
336    * dimensionality.  The radii of the iterators are ignored. */
337   bool operator>=(const Self &it) const
338     {    return  this->GetCenterPointer() >= it.GetCenterPointer();  }
339
340   /** This method positions the iterator at an indexed location in the
341    * image. SetLocation should _NOT_ be used to update the position of the
342    * iterator during iteration, only for initializing it to a position
343    * prior to iteration.  This method is not optimized for speed. */
344   void SetLocation( const IndexType& position )
345     {
346 IND ******this->SetLoop(position);
347 IND ******this->SetPixelPointers(position);
348     }
349   
350
351   /** Addition of an itk::Offset.  Note that this method does not do any bounds
352    * checking.  Adding an offset that moves the iterator out of its assigned
353    * region will produce undefined results. */
354   Self &operator+=(const OffsetType &);
355
356 LEN   /** Subtraction of an itk::Offset. Note that this method does not do any bounds
357    * checking.  Subtracting an offset that moves the iterator out of its
358    * assigned region will produce undefined results. */
359   Self &operator-=(const OffsetType &);
360
361   /** Distance between two iterators */
362   OffsetType operator-(const Self& b)
363 IND **{  return m_Loop - b.m_Loop;  }
364
365 IND */** Returns false if the iterator overlaps region boundaries, true
366    * otherwise.  Also updates an internal boolean array indicating
367    * which of the iterator's faces are out of bounds. */
368   bool InBounds() const;
369
370   /** Allows a user to override the internal boundary condition. Care should
371    * be taken to ensure that the overriding boundary condition is a persistent
372    * object during the time it is referenced.  The overriding condition
373    * can be of a different type than the default type as long as it is
374    * a subclass of ImageBoundaryCondition. */
375 LEN   virtual void OverrideBoundaryCondition(const ImageBoundaryConditionPointerType i)
376     { m_BoundaryCondition = i; }
377
378   /** Resets the boundary condition to the internal, default conditions
379    * specified by the template parameter. */
380   virtual void ResetBoundaryCondition()
381     { m_BoundaryCondition = &m_InternalBoundaryCondition;  }
382
383   /** Sets the internal, default boundary condition. */
384   void SetBoundaryCondition( const TBoundaryCondition &c )
385 IND **{ m_InternalBoundaryCondition = c; }
386
387 IND ***/** */
388   const BoundaryConditionType *GetBoundaryCondition() const
389 IND **{ return dynamic_cast<BoundaryConditionType *>(m_BoundaryCondition); }
390
391   /** */
392   void NeedToUseBoundaryConditionOn()
393 IND **{
394     this->SetNeedToUseBoundaryCondition(true);
395 IND **}
396   void NeedToUseBoundaryConditionOff()
397 IND **{
398     this->SetNeedToUseBoundaryCondition(false);
399 IND **}
400   void SetNeedToUseBoundaryCondition(bool b)
401 IND **{
402     m_NeedToUseBoundaryCondition = b;
403 IND **}
404   bool GetNeedToUseBoundaryCondition() const
405 IND **{
406     return m_NeedToUseBoundaryCondition;
407 IND **}
408   
409   
410 protected:
411   
412   /** Default method for setting the coordinate location of the iterator.
413    * Loop indicies correspond to the actual Image region index. */
414   virtual void SetLoop( const IndexType& p )
415     {  m_Loop = p; m_IsInBoundsValid = false;}
416   
417   /** Virtual method for setting internal loop boundaries.  This
418    * method must be defined in each subclass because
419    * each subclass may handle loop boundaries differently. */
420   virtual void SetBound(const SizeType &);
421
422   /** Default method for setting the values of the internal pointers
423    * to itk::Image memory buffer locations.  This method should
424    * generally only be called when the iterator is initialized.
425    * \sa SetLocation */
426   virtual void SetPixelPointers(const IndexType &);
427
428   /** Default method for setting the index of the first pixel in the
429    * iteration region. */
430   virtual void SetBeginIndex( const IndexType& start)
431     {  m_BeginIndex = start;  }
432
433   /** Default method for setting the index of the first pixel in the
434    * iteration region. */
435   virtual void SetEndIndex();
436   
437   /** The starting index for iteration within the itk::Image region
438    * on which this ConstNeighborhoodIterator is defined. */
439   IndexType m_BeginIndex;
440
441   /** An array of upper looping boundaries used during iteration. */
442   IndexType m_Bound;
443
444   /** A pointer to the first pixel in the iteration region. */
445   const InternalPixelType *m_Begin;
446   
447   /** The image on which iteration is defined. */
448   typename ImageType::ConstWeakPointer m_ConstImage;
449
450   /*
451 IND **** A pointer to one past the last pixel in the iteration region.
452 IND ****/
453   const InternalPixelType *m_End;
454
455   /** The end index for iteration within the itk::Image region
456    * on which this ConstNeighborhoodIterator is defined. */
457   IndexType m_EndIndex;
458
459   /** Array of loop counters used during iteration. */
460   IndexType m_Loop;
461  
462   /** The region over which iteration is defined. */
463   RegionType m_Region;
464
465 LEN   /** The internal array of offsets that provide support for regions of interest.
466    * An offset for each dimension is necessary to shift pointers when wrapping
467    * around region edges because region memory is not necessarily contiguous
468    * within the buffer. */
469   OffsetType m_WrapOffset;
470
471   /** Pointer to the actual boundary condition that will be used.
472    * By default this points to m_BoundaryCondition, but
473    * OverrideBoundaryCondition allows a user to point this variable an external
474    * boundary condition.  */
475   ImageBoundaryConditionPointerType m_BoundaryCondition;
476
477 IND ***/** Denotes which of the iterators dimensional sides spill outside
478    * region of interest boundaries. */
479   mutable bool m_InBounds[Dimension];
480
481   /** Denotes if iterator is entirely within bounds */
482   mutable bool m_IsInBounds;
483   
484   /** Is the m_InBounds and m_IsInBounds variables up to date? Set to
485    * false whenever the iterator is repositioned.  Set to true within
486    * InBounds(). */
487   mutable bool m_IsInBoundsValid;
488   
489   /** Lower threshold of in-bounds loop counter values. */
490   IndexType m_InnerBoundsLow;
491   
492   /** Upper threshold of in-bounds loop counter values. */
493   IndexType m_InnerBoundsHigh;
494
495   /** Default boundary condition. */
496   TBoundaryCondition m_InternalBoundaryCondition;
497
498   /** Does the specified region need to worry about boundary conditions? **/
499   bool m_NeedToUseBoundaryCondition;
500
501   /** Functor type used to access neighborhoods of pixel pointers */
502   NeighborhoodAccessorFunctorType m_NeighborhoodAccessorFunctor;
503
504 };
505
506 template<class TImage>
507 inline ConstNeighborhoodIterator<TImage>
508 operator+(const ConstNeighborhoodIterator<TImage> &it,
509           const typename ConstNeighborhoodIterator<TImage>
510           ::OffsetType &ind)
511 {
512   ConstNeighborhoodIterator<TImage> ret;
513   ret = it;
514   ret += ind;
515   return ret;
516 }
517
518 template<class TImage>
519 inline ConstNeighborhoodIterator<TImage>
520 operator+(const typename ConstNeighborhoodIterator<TImage>
521           ::OffsetType &ind,
522           const ConstNeighborhoodIterator<TImage> &it)
523 {  return (it + ind); }
524
525 template<class TImage>
526 inline ConstNeighborhoodIterator<TImage>
527 operator-(const ConstNeighborhoodIterator<TImage> &it,
528           const typename ConstNeighborhoodIterator<TImage>
529           ::OffsetType &ind)
530 {
531   ConstNeighborhoodIterator<TImage> ret;
532   ret = it;
533   ret -= ind;
534   return ret;
535 }
536
537
538 EML
539 EML
540 EML
541 EML
542 EML
543 EML
544 EML
545 EML
546 EML
547 EML
548   
549 // namespace itk
550
551
552 #ifndef ITK_MANUAL_INSTANTIATION
553 #include "itkConstNeighborhoodIterator.txx"
554 #endif
555
556 #endif
557

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:03PM
© Kitware Inc.