KWStyle - itkNeighborhoodIterator.h
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkNeighborhoodIterator.h.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:42 $
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 __itkNeighborhoodIterator_h
18 #define __itkNeighborhoodIterator_h
19
20 #include <vector>
21 #include <string.h>
22 #include <iostream>
23 #include "itkConstNeighborhoodIterator.h"
24
25 namespace itk {
26
27 /**
28  * \class NeighborhoodIterator
29  * \brief  Defines iteration of a local N-dimensional neighborhood of pixels
30  * across an itk::Image.
31  *
32  * This class is a loose extension of the Standard Template Library (STL)
33  * bi-directional iterator concept to \em masks of pixel neighborhoods within
34  * itk::Image objects.  This NeighborhoodIterator base class defines simple
35  * forward and reverse iteration of an N-dimensional neighborhood mask
36  * across an image.  Elements within the mask can be accessed like elements
37  * within an array.
38  *
39  * NeighborhoodIterators are designed to encapsulate some of the complexity of
40  * working with image neighborhoods, complexity that would otherwise have to be
41  * managed at the algorithmic level.  Use NeighborhoodIterators to simplify
42  * writing algorithms that perform geometrically localized operations on images
43  * (for example, convolution and morphological operations).
44  *
45  * To motivate the discussion of NeighborhoodIterators and their use in
46  * Itk, consider the following code that takes directional derivatives at each
47  * point in an image.
48  *
49  * \code
50  * itk::NeighborhoodInnerProduct<ImageType> IP;
51  *
52  * itk::DerivativeOperator<ImageType> operator;
53  *  operator->SetOrder(1);
54  *  operator->SetDirection(0);
55  *  operator->CreateDirectional();
56  *
57  * itk::NeighborhoodIterator<ImageType>
58  *   iterator(operator->GetRadius(), myImage, myImage->GetRequestedRegion());
59  *
60  * iterator.SetToBegin();
61  * while ( ! iterator.IsAtEnd() )
62  * {
63 IND **   std::cout << "Derivative at index " << iterator.GetIndex() << is <<
64  *     IP(iterator, operator) << std::endl;
65  *   ++iterator;
66  * } 
67  * \endcode
68  *
69  * Most of the work for the programmer in the code above is in setting up for
70  * the iteration.  There are three steps.  First an inner product function
71  * object is created which will be used to effect convolution with the
72  * derivative kernel.  Setting up the derivative kernel, DerivativeOperator,
73  * involves setting the order and direction of the derivative.  Finally, we
74  * create an iterator over the RequestedRegion of the itk::Image (see Image)
75  * using the radius of the derivative kernel as the size.
76  *
77  * Itk iterators only loosely follow STL conventions.  Notice that instead of
78  * asking myImage for myImage.begin() and myImage.end(), iterator.SetToBegin()
79  * and iterator.IsAtEnd() are called.  Itk iterators are typically more complex
80  * objects than traditional, pointer-style STL iterators, and the increased
81  * overhead required to conform to the complete STL API is not always
82  * justified.
83  *
84  * The API for creating and manipulating a NeighborhoodIterator mimics
85  * that of the itk::ImageIterators.  Like the itk::ImageIterator, a
86 LEN  * ConstNeighborhoodIterator is defined on a region of interest in an itk::Image.
87  * Iteration is constrained within that region of interest.
88  *
89  * A NeighborhoodIterator is constructed as a container of pointers (offsets)
90  * to a geometric neighborhood of image pixels.  As the central pixel position
91  * in the mask is moved around the image, the neighboring pixel pointers
92  * (offsets) are moved accordingly.
93  *
94  * A \em pixel \em neighborhood is defined as a central pixel location and an
95  * N-dimensional radius extending outward from that location.
96  
97  * Pixels in a neighborhood can be accessed through a NeighborhoodIterator
98  * like elements in an array.  For example, a 2D neighborhood with radius 2x1
99  * has indices:
100  *
101  * \code
102  *
103  * 0  1  2  3  4
104  * 5  6  7  8  9
105  * 10 11 12 13 14
106  *
107  * \endcode
108  *
109  * Now suppose a NeighborhoodIterator with the above dimensions is constructed
110  * and positioned over a neighborhood of values in an Image:
111  *
112  * \code
113  *
114  * 1.2 1.3 1.8 1.4 1.1
115 WCM  * 1.8 1.1 0.7 1.0 1.0
116  * 2.1 1.9 1.7 1.4 2.0
117  *
118  * \endcode
119  *
120  * Shown below is some sample pixel access code and the values that it returns.
121  *
122  * \code
123  *
124  * ::size_t c = (::size_t) (iterator.Size() / 2); // get offset of center pixel
125  * ::size_t s = iterator.GetStride(1);            // y-dimension step size
126  *
127  * std::cout << iterator.GetPixel(7)      << std::endl;
128  * std::cout << iterator.GetCenterPixel() << std::endl;
129  * std::cout << iterator.GetPixel(c)      << std::endl;
130  * std::cout << iterator.GetPixel(c-1)    << std::endl;
131  * std::cout << iterator.GetPixel(c-s)    << std::endl;
132  * std::cout << iterator.GetPixel(c-s-1)  << std::endl; 
133  * std::cout << *iterator[c]              << std::endl;
134  *
135  * \endcode
136  *
137  * Results:
138  *
139  * \code
140  * 0.7
141  * 0.7
142  * 0.7
143  * 1.1
144  * 1.8
145  * 1.3
146  * 0.7
147  * \endcode
148  *
149  * Use of GetPixel() is preferred over the *iterator[] form, and can be used
150  * without loss of efficiency in most cases. Some variations (subclasses) of
151  * NeighborhoodIterators may exist which do not support the latter
152  * API. Corresponding SetPixel() methods exist to modify pixel values in
153  * non-const NeighborhoodIterators.
154  *
155  * NeighborhoodIterators are "bidirectional iterators". They move only in two
156  * directions through the data set.  These directions correspond to the layout
157  * of the image data in memory and not to spatial directions of the
158  * N-dimensional itk::Image.  Iteration always proceeds along the fastest
159  * increasing dimension (as defined by the layout of the image data) .  For
160  * itk::Image this is the first dimension specified (i.e. for 3-dimensional
161  * (x,y,z) NeighborhoodIterator proceeds along the x-dimension) (For random
162  * access iteration through N-dimensional indicies, use
163  * RandomAccessNeighborhoodIterator.)
164  *
165  * Each subclass of a ConstNeighborhoodIterator may also define its own
166  * mechanism for iteration through an image.  In general, the Iterator does not
167  * directly keep track of its spatial location in the image, but uses a set of
168  * internal loop variables and offsets to trigger wraps at itk::Image region
169  * boundaries, and to identify the end of the itk::Image region.
170  *
171  * 
172  * \todo Better support for regions with negative indicies.
173  * \todo Add Begin() and End() methods?
174  *
175  * \sa DerivativeOperator \sa NeighborhoodInnerProduct
176  *
177  * \par MORE INFORMATION
178  * For a complete description of the ITK Image Iterators and their API, please
179  * see the Iterators chapter in the ITK Software Guide.  The ITK Software Guide
180  * is available in print and as a free .pdf download from http://www.itk.org.
181  *
182  * \ingroup ImageIterators
183  *
184  * \sa ImageConstIterator \sa ConditionalConstIterator
185  * \sa ConstNeighborhoodIterator \sa ConstShapedNeighborhoodIterator
186  * \sa ConstSliceIterator  \sa CorrespondenceDataStructureIterator 
187  * \sa FloodFilledFunctionConditionalConstIterator 
188  * \sa FloodFilledImageFunctionConditionalConstIterator 
189  * \sa FloodFilledImageFunctionConditionalIterator 
190  * \sa FloodFilledSpatialFunctionConditionalConstIterator 
191  * \sa FloodFilledSpatialFunctionConditionalIterator 
192  * \sa ImageConstIterator \sa ImageConstIteratorWithIndex 
193  * \sa ImageIterator \sa ImageIteratorWithIndex
194  * \sa ImageLinearConstIteratorWithIndex  \sa ImageLinearIteratorWithIndex 
195  * \sa ImageRandomConstIteratorWithIndex  \sa ImageRandomIteratorWithIndex 
196  * \sa ImageRegionConstIterator \sa ImageRegionConstIteratorWithIndex 
197  * \sa ImageRegionExclusionConstIteratorWithIndex 
198  * \sa ImageRegionExclusionIteratorWithIndex 
199  * \sa ImageRegionIterator  \sa ImageRegionIteratorWithIndex 
200  * \sa ImageRegionReverseConstIterator  \sa ImageRegionReverseIterator 
201  * \sa ImageReverseConstIterator  \sa ImageReverseIterator 
202  * \sa ImageSliceConstIteratorWithIndex  \sa ImageSliceIteratorWithIndex 
203  * \sa NeighborhoodIterator \sa PathConstIterator  \sa PathIterator 
204  * \sa ShapedNeighborhoodIterator  \sa SliceIterator 
205  * \sa ImageConstIteratorWithIndex
206  *
207  * \ingroup Operators
208  */
209 template<class TImage, class TBoundaryCondition
210                        = ZeroFluxNeumannBoundaryCondition<TImage> >
211 class ITK_EXPORT NeighborhoodIterator
212 IND **:  public ConstNeighborhoodIterator<TImage,TBoundaryCondition>
213 {
214 public:
215   /** Standard class typedefs. */
216   typedef NeighborhoodIterator Self;
217 TDA   typedef ConstNeighborhoodIterator<TImage,TBoundaryCondition> Superclass;
218   
219   /** Extract typedefs from superclass. */
220   typedef typename Superclass::InternalPixelType InternalPixelType;
221 TDA   typedef typename Superclass::PixelType  PixelType;
222 TDA   typedef typename Superclass::SizeType   SizeType;
223 TDA   typedef typename Superclass::ImageType  ImageType;
224 TDA   typedef typename Superclass::RegionType RegionType;
225 TDA   typedef typename Superclass::IndexType  IndexType;
226 TDA   typedef typename Superclass::OffsetType OffsetType;
227 TDA   typedef typename OffsetType::OffsetValueType OffsetValueType;
228 TDA   typedef typename Superclass::RadiusType RadiusType;
229 TDA   typedef typename Superclass::NeighborhoodType NeighborhoodType;
230 TDA   typedef typename Superclass::Iterator      Iterator;
231 TDA   typedef typename Superclass::ConstIterator ConstIterator;
232   typedef typename Superclass::ImageBoundaryConditionPointerType
233 TDA,IND ***ImageBoundaryConditionPointerType;
234     
235   /** Default constructor. */
236   NeighborhoodIterator(): Superclass() {}
237   
238   /** Copy constructor */
239   NeighborhoodIterator( const NeighborhoodIterator &n )
240 IND ****: Superclass(n) {}
241   
242   /** Assignment operator */
243   Self &operator=(const Self& orig)
244     {
245 IND ******Superclass::operator=(orig);
246 IND ******return *this;
247     }
248   
249   /** Constructor which establishes the region size, neighborhood, and image
250    * over which to walk. */
251   NeighborhoodIterator(const SizeType &radius, ImageType * ptr,
252                        const RegionType ®ion)
253 IND ****: Superclass(radius, ptr, region) { }
254
255   /** Standard print method */
256   virtual void PrintSelf(std::ostream &, Indent) const;
257
258   /** Returns the central memory pointer of the neighborhood. */
259   InternalPixelType *GetCenterPointer()
260     { return (this->operator[]((this->Size())>>1)); }
261
262   /** Returns the central pixel of the neighborhood. */
263   virtual void SetCenterPixel(const PixelType &p)
264 LEN,IND **{ this->m_NeighborhoodAccessorFunctor.Set(this->operator[]((this->Size())>>1), p); }
265   
266   /** Virtual function that replaces the pixel values in the image
267    * neighborhood that are pointed to by this NeighborhoodIterator with
268    * the pixel values contained in a Neighborhood. */
269   virtual void SetNeighborhood(const NeighborhoodType &);
270
271   /** Special SetPixel method which quietly ignores out-of-bounds attempts.
272    *  Sets status TRUE if pixel has been set, FALSE otherwise.  */
273   virtual void SetPixel(const unsigned i, const PixelType &v,
274                         bool  &status);
275   
276   /** Set the pixel at the ith location. */
277   virtual void SetPixel(const unsigned i, const PixelType &v);
278   //  { *(this->operator[](i)) = v; }
279   
280   /** Set the pixel at offset o from the neighborhood center */
281   virtual void SetPixel(const OffsetType o, const PixelType &v)
282 IND **{ this->SetPixel(this->GetNeighborhoodIndex(o), v); }
283 IND ****//  { *(this->operator[](o)) = v; }
284
285 LEN   /** Sets the pixel value located i pixels distant from the neighborhood center in
286 IND ******the positive specified ``axis'' direction. No bounds checking is done on
287 IND ******the size of the neighborhood. */
288   virtual void SetNext(const unsigned axis, const unsigned i,
289                             const PixelType &v)
290 IND **{   this->SetPixel(this->GetCenterNeighborhoodIndex()
291 IND *********************+ (i * this->GetStride(axis)), v); }
292   
293   
294 LEN   /** Sets the pixel value located one pixel distant from the neighborhood center in
295 IND ******the specifed positive axis direction. No bounds checking is done on the
296 IND ******size of the neighborhood. */
297   virtual void SetNext(const unsigned axis, const PixelType &v)
298     {   this->SetPixel(this->GetCenterNeighborhoodIndex()
299 IND ***********************+ this->GetStride(axis), v); }
300   
301 LEN   /** Sets the pixel value located i pixels distant from the neighborhood center in
302 IND ******the negative specified ``axis'' direction. No bounds checking is done on
303 IND ******the size of the neighborhood. */
304   virtual void SetPrevious(const unsigned axis, const unsigned i,
305                                 const PixelType &v)
306     { this->SetPixel(this->GetCenterNeighborhoodIndex()
307 IND *********************- (i * this->GetStride(axis)), v); }
308   
309   
310 LEN   /** Sets the pixel value located one pixel distant from the neighborhood center in
311 IND ******the specifed negative axis direction. No bounds checking is done on the
312 IND ******size of the neighborhood. */
313   virtual void SetPrevious(const unsigned axis,
314                                 const PixelType &v)
315     { this->SetPixel(this->GetCenterNeighborhoodIndex()
316 IND *********************- this->GetStride(axis), v); }
317   
318 };
319
320 // namespace itk
321
322
323 #ifndef ITK_MANUAL_INSTANTIATION
324 #include "itkNeighborhoodIterator.txx"
325 #endif
326
327 #endif
328

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