KWStyle - itkNeighborhood.h
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkNeighborhood.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 __itkNeighborhood_h
18 #define __itkNeighborhood_h
19
20 #include <iostream>
21 #include "itkNeighborhoodAllocator.h"
22 #include "itkSize.h"
23 #include "itkIndent.h"
24 #include "itkSliceIterator.h"
25 #include "vnl/vnl_vector.h"
26 #include "itkOffset.h"
27 #include <vector>
28
29 namespace itk {
30   
31 /** \class Neighborhood
32  * \brief A light-weight container object for storing an N-dimensional
33  * neighborhood of values. 
34  *
35  * This class serves as the base class for several other Itk objects such as
36  * itk::NeighborhoodOperator and itk::NeighborhoodIterator.  Its purpose is to
37  * store values and their relative spatial locations.
38  *
39  * A Neighborhood has an N-dimensional \em radius.  The radius is defined
40  * separately for each dimension as the number of pixels that the neighborhood
41  * extends outward from the center pixel.  For example, a 2D Neighborhood
42  * object with a radius of 2x3 has sides of length 5x7.  Neighborhood objects
43  * always have an unambiguous center because their side lengths are always odd.
44  *
45  * \sa Neighborhood
46  * \sa NeighborhoodIterator
47  * 
48  * \ingroup Operators
49  * \ingroup ImageIterators
50  */
51
52 template<class TPixel, unsigned int VDimension = 2,
53          class TAllocator = NeighborhoodAllocator<TPixel> >
54 class ITK_EXPORT Neighborhood 
55 {
56 public:
57   /** Standard class typedefs. */
58   typedef Neighborhood Self;
59
60   /** External support for allocator type. */
61   typedef TAllocator AllocatorType;
62
63   /** External support for dimensionality. */
64   itkStaticConstMacro(NeighborhoodDimension, unsigned int, VDimension);
65   
66   /** External support for pixel type. */
67   typedef TPixel PixelType;
68   
69   /** Iterator typedef support. Note the naming is intentional, i.e.,
70 IND *** ::iterator and ::const_iterator, because the allocator may be a
71 IND *** vnl object or other type, which uses this form. */
72   typedef typename AllocatorType::iterator Iterator;
73 TDA   typedef typename AllocatorType::const_iterator ConstIterator;
74   
75   /** Size and value typedef support. */
76   typedef Size<VDimension> SizeType;
77 TDA   typedef typename SizeType::SizeValueType SizeValueType;
78   
79   /** Radius typedef support. */
80   typedef Size<VDimension> RadiusType;
81
82   /** Offset type used to reference neighbor locations */
83   typedef Offset<VDimension> OffsetType;
84   
85   /** External slice iterator type typedef support. */
86   typedef SliceIterator<TPixel, Self> SliceIteratorType;
87   
88   /** Default constructor. */
89   Neighborhood() { m_Radius.Fill(0); m_Size.Fill(0);  }
90
91   /** Default destructor. */
92   virtual ~Neighborhood() {}
93     
94   /** Copy constructor. */
95   Neighborhood(const Self& other);
96
97   /** Assignment operator. */
98   Self &operator=(const Self& other);
99
100   /** Comparison operator. */
101   bool
102   operator==(const Self& other) const
103 IND **{
104     return (m_Radius == other.m_Radius &&
105             m_Size   == other.m_Size &&
106             m_DataBuffer == other.m_DataBuffer);
107 IND **}
108
109   /** Not Equal operator. */
110   bool operator!=(const Self& other) const
111 IND **{
112     return (m_Radius != other.m_Radius ||
113             m_Size   != other.m_Size ||
114             m_DataBuffer != other.m_DataBuffer);
115 IND **}
116
117   /** Returns the radius of the neighborhood. */
118   const SizeType GetRadius() const
119     { return m_Radius; }
120
121   /** Returns the radius of the neighborhood along a specified
122    * dimension. */
123   unsigned long GetRadius(const unsigned long n) const
124     { return m_Radius[n]; }
125
126   /** Returns the size (total length) of the neighborhood along
127    * a specified dimension. */
128   unsigned long GetSize(const unsigned long n) const
129     { return m_Size[n]; }
130
131   /** Returns the size (total length of sides) of the neighborhood. */
132   SizeType GetSize() const
133     { return m_Size; }
134   
135   /** Returns the stride length for the specified dimension. Stride
136    * length is the number of pixels between adjacent pixels along the
137    * given dimension. */
138   unsigned GetStride(const unsigned axis) const
139 IND **{     return m_StrideTable[axis];  }
140   
141   /** STL-style iterator support. */
142   Iterator End()
143     { return m_DataBuffer.end(); }
144   Iterator Begin()
145     { return m_DataBuffer.begin(); }
146   ConstIterator End() const
147     { return m_DataBuffer.end(); }
148   ConstIterator Begin() const
149     { return m_DataBuffer.begin(); }
150   
151   /** More STL-style support. */
152   unsigned int Size() const
153     { return m_DataBuffer.size(); }
154   
155   /** Pass-through data access methods to the buffer. */
156   TPixel &operator[](unsigned int i)
157     { return m_DataBuffer[i]; }
158   const TPixel &operator[](unsigned int i) const
159 IND **{ return m_DataBuffer[i]; }
160   TPixel &GetElement(unsigned int i) 
161 IND **{ return m_DataBuffer[i]; }
162
163   /** Returns the element at the center of the neighborhood. */
164   TPixel GetCenterValue() const
165 IND **{    return (this->operator[]((this->Size())>>1)); }
166
167   /** Sets the radius for the neighborhood, calculates size from the
168    * radius, and allocates storage. */
169   void SetRadius(const SizeType &);
170
171   /** Sets the radius for the neighborhood. Overloaded to support an unsigned
172    * long array. */
173   void SetRadius(const unsigned long *rad)
174 IND **{
175     SizeType s;
176     memcpy(s.m_Size, rad, sizeof(unsigned long) * VDimension);
177     this->SetRadius(s);
178 IND **}
179   
180   /** Overloads SetRadius to allow a single long integer argument
181    * that is used as the radius of all the dimensions of the
182    * Neighborhood (resulting in a "square" neighborhood). */
183   void SetRadius(const unsigned long);
184
185   /** Standard itk object method. */
186   void Print(std::ostream& os) const
187     { this->PrintSelf(os, Indent(0));  }
188
189   /** Returns a reference to the data buffer structure. */
190   AllocatorType &GetBufferReference()
191     { return m_DataBuffer; }
192   const AllocatorType &GetBufferReference() const
193     { return m_DataBuffer; }
194
195   /** Get pixel value by offset */
196   TPixel &operator[](const OffsetType &o)
197 IND **{    return this->operator[](this->GetNeighborhoodIndex(o)); }
198   const TPixel &operator[](const OffsetType &o) const
199 IND **{ return this->operator[](this->GetNeighborhoodIndex(o)); }
200
201   /** Returns the itk::Offset from the center of the Neighborhood to
202 IND ******the requested neighbor index. */
203   OffsetType GetOffset(unsigned int i) const
204 IND **{    return m_OffsetTable[i];  }
205
206   virtual unsigned int GetNeighborhoodIndex(const OffsetType &) const;
207
208   unsigned int GetCenterNeighborhoodIndex() const
209 IND **{ return  static_cast<unsigned int>(this->Size()/2); }
210     
211   std::slice GetSlice(unsigned int) const;
212   
213 protected:
214   /** Sets the length along each dimension. */
215   void SetSize()
216 IND **{
217     for (unsigned int i=0; i<VDimension; ++i)
218       { m_Size[i] = m_Radius[i]*2+1; }
219   }
220
221   /** Allocates the neighborhood's memory buffer. */
222   virtual void Allocate(unsigned int i)
223     { m_DataBuffer.set_size(i); }
224
225   /** Standard itk object method. */
226   virtual void PrintSelf(std::ostream&, Indent) const;
227
228   /** Computes the entries for the stride table */
229   virtual void ComputeNeighborhoodStrideTable();
230
231   /** Fills entries into the offset lookup table. Called once on
232       initialization. */
233   virtual void ComputeNeighborhoodOffsetTable();
234
235 private:
236   /** Number of neighbors to include (symmetrically) along each axis.
237    * A neighborhood will always have odd-length axes (m_Radius[n]*2+1). */
238   SizeType m_Radius;
239
240   /** Actual length of each dimension, calculated from m_Radius.
241    * A neighborhood will always have odd-length axes (m_Radius[n]*2+1). */
242   SizeType m_Size;
243
244   /** The buffer in which data is stored. */
245   AllocatorType m_DataBuffer;
246
247   /** A lookup table for keeping track of stride lengths in a neighborhood
248       i.e. the memory offsets between pixels along each dimensional axis */
249   unsigned int m_StrideTable[VDimension];
250
251   /** */
252   std::vector<OffsetType> m_OffsetTable;
253
254 };
255
256 template <class TPixel, unsigned int VDimension, class TContainer>
257 LEN std::ostream & operator<<(std::ostream &os, const Neighborhood<TPixel,VDimension,TContainer> &neighborhood)
258 {
259   os << "Neighborhood:" << std::endl;
260   os << "    Radius:" << neighborhood.GetRadius() << std::endl;
261   os << "    Size:" << neighborhood.GetSize() << std::endl;
262   os << "    DataBuffer:" << neighborhood.GetBufferReference() << std::endl;
263
264   return os;
265 }
266
267 // namespace itk
268
269 #ifndef ITK_MANUAL_INSTANTIATION
270 #include "itkNeighborhood.txx"
271 #endif
272
273 #endif
274

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