KWStyle - itkSpecialCoordinatesImage.h
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkSpecialCoordinatesImage.h.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:48 $
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 __itkSpecialCoordinatesImage_h
18 #define __itkSpecialCoordinatesImage_h
19
20 #include "itkImageBase.h"
21 #include "itkImageRegion.h"
22 #include "itkImportImageContainer.h"
23 #include "itkDefaultPixelAccessor.h"
24 #include "itkDefaultPixelAccessorFunctor.h"
25 #include "itkPoint.h"
26 #include "itkContinuousIndex.h"
27 #include "itkFixedArray.h"
28
29 namespace itk
30 {
31
32 /** \class SpecialCoordinatesImage
33  *  \brief Templated n-dimensional nonrectilinear-coordinate image base class.
34  *
35  * SpecialCoordinatesImages are templated over a pixel type (modeling the
36  * dependent variables), and a dimension (number of independent variables).
37  * The container for the pixel data is the ImportImageContainer.
38  *
39  * Within the pixel container, images are modeled as arrays, defined by a
40  * start index and a size.
41  * 
42  * Almost arbitrary mappings between index space & Cartesian physical space are
43  * possible, and so m_Origin and m_Spacing should be ignored.  They exist only
44  * to allow the possibility of running a "spatially-aware" filter in raw index
45  * space, as if the SpecialCoordinatesImage data was laid out on a regular grid.
46 WCM  * Note that this may or may not produce useful results, and it is up the the
47  * user to determine the appropriateness of running a filter designed for normal
48  * images on special-coordinates images.
49  * 
50  * The only correct generic method for operating on a SpecialCoordinatesImage in
51  * physical space is to use the virtual functions TransformPhysicalPointToIndex,
52  * TransformPhysicalPointToContinuousIndex, TransformIndexToPhysicalPoint, and
53  * TransformContinuousIndexToPhysicalPoint.  All of these methods transform
54  * points in Cartesian physical space to and from indices in the special
55  * (typically non-Cartesian) index space.  It is also possible to check the
56  * type of coordinate representation being used by a SpecialCoordinatesImage,
57  * and then use representation-specific code to speed up the filter for certain
58  * coordinate representations, falling back to the generic method for
59  * unrecognized and/or unoptimized coordinate representations.
60  *
61  * There are three sets of meta-data describing portians of a
62  * SpecialCoordinatesImages. These are "Region" objects that define a portion of
63  * an image via a starting index for the image array and a size. The ivar
64  * LargestPossibleRegion defines the size and starting index of the image
65  * dataset. The entire image dataset, however, need not be resident in memory.
66  * The region of the image that is resident in memory is defined by the
67  * "BufferedRegion". The Buffer is a contiguous block of memory.  The third set
68  * of meta-data defines a region of interest, called the "RequestedRegion". The
69  * RequestedRegion is used by the pipeline execution model to define what a
70  * filter is requested to produce.
71  *
72  * [RegionIndex, RegionSize] C [BufferIndex, BufferSize]
73  *                           C [ImageIndex, ImageSize]
74  *
75  * Pixels can be accessed direcly using the SetPixel() and GetPixel()
76  * methods or can be accessed via iterators.  Begin() creates
77  * an iterator that can walk a specified region of a buffer.
78  *
79  * The pixel type may be one of the native types; a Insight-defined
80  * class type such as Vector; or a user-defined type. Note that
81  * depending on the type of pixel that you use, the process objects
82  * (i.e., those filters processing data objects) may not operate on
83  * the image and/or pixel type. This becomes apparent at compile-time
84  * because operator overloading (for the pixel type) is not supported.
85  *
86  * The data in an image is arranged in a 1D array as [][][][slice][row][col]
87  * with the column index varying most rapidly.  The Index type reverses
88  * the order so that with Index[0] = col, Index[1] = row, Index[2] = slice,
89  * ...
90  *
91  * \sa ImageContainerInterface
92  * \sa Image
93  *
94  * \ingroup ImageObjects */
95 template <class TPixel, unsigned int VImageDimension=2>
96 class ITK_EXPORT SpecialCoordinatesImage : public ImageBase<VImageDimension>
97 {
98 public:
99   /** Standard class typedefs */
100   typedef SpecialCoordinatesImage     Self;
101   typedef ImageBase<VImageDimension>  Superclass;
102 TDA   typedef SmartPointer<Self>  Pointer;
103 TDA   typedef SmartPointer<const Self>  ConstPointer;
104 TDA   typedef WeakPointer<const Self>  ConstWeakPointer;
105
106   /** Method for creation through the object factory. */
107   itkNewMacro(Self);
108
109   /** Run-time type information (and related methods). */
110   itkTypeMacro(SpecialCoordinatesImage, ImageBase);
111
112   /** Pixel typedef support. Used to declare pixel type in filters
113    * or other operations. */
114   typedef TPixel PixelType;
115
116   /** Typedef alias for PixelType */
117 SEM   typedef TPixel ValueType ;
118
119   /** Internal Pixel representation. Used to maintain a uniform API
120    * with Image Adaptors and allow to keep a particular internal
121    * representation of data while showing a different external
122    * representation. */
123   typedef TPixel InternalPixelType;
124
125   typedef PixelType  IOPixelType;
126
127   /** Accessor type that convert data between internal and external
128    *  representations.  */
129   typedef DefaultPixelAccessor< PixelType > AccessorType;
130
131   /** Accessor functor to choose between accessors: DefaultPixelAccessor for
132    * the Image, and DefaultVectorPixelAccessor for the vector image. The 
133    * functor provides a generic API between the two accessors.*/
134   typedef DefaultPixelAccessorFunctor< Self > AccessorFunctorType;
135
136   /** Dimension of the image.  This constant is used by functions that are
137    * templated over image type (as opposed to being templated over pixel type
138    * and dimension) when they need compile time access to the dimension of
139    * the image. */
140   itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension);
141
142   /** Container used to store pixels in the image. */
143   typedef ImportImageContainer<unsigned long, PixelType> PixelContainer;
144
145   /** Index typedef support. An index is used to access pixel values. */
146   typedef typename Superclass::IndexType  IndexType;
147
148   /** Offset typedef support. An offset is used to access pixel values. */
149   typedef typename Superclass::OffsetType OffsetType;
150
151   /** Size typedef support. A size is used to define region bounds. */
152   typedef typename Superclass::SizeType  SizeType;
153
154 LEN   /** Region typedef support. A region is used to specify a subset of an image. */
155   typedef typename Superclass::RegionType  RegionType;
156
157   /** Spacing typedef support.  Spacing holds the "fake" size of a pixel, making
158    * each pixel look like a 1 unit hyper-cube to filters that were designed for
159    * normal images and that therefore use m_Spacing.  The spacing is the
160    * geometric distance between image samples. */
161   typedef typename Superclass::SpacingType SpacingType;
162
163   /** Origin typedef support.  The origin is the "fake" geometric coordinates
164    * of the index (0,0).  Also for use w/ filters designed for normal images. */
165   typedef typename Superclass::PointType PointType;
166
167   /** A pointer to the pixel container. */
168   typedef typename PixelContainer::Pointer PixelContainerPointer;
169 TDA   typedef typename PixelContainer::ConstPointer PixelContainerConstPointer;
170
171   /** Allocate the image memory. The size of the image must
172    * already be set, e.g. by calling SetRegions(). */
173   void Allocate();
174
175   /** Convenience methods to set the LargestPossibleRegion,
176    *  BufferedRegion and RequestedRegion. Allocate must still be called.
177    */
178   void SetRegions(RegionType region)
179     {
180     this->SetLargestPossibleRegion(region);
181     this->SetBufferedRegion(region);
182     this->SetRequestedRegion(region);
183     };
184
185   void SetRegions(SizeType size)
186     {
187     RegionType region; region.SetSize(size);
188     this->SetLargestPossibleRegion(region);
189     this->SetBufferedRegion(region);
190     this->SetRequestedRegion(region);
191     };
192
193   /** Restore the data object to its initial state. This means releasing
194    * memory. */
195   virtual void Initialize();
196
197   /** Fill the image buffer with a value.  Be sure to call Allocate()
198    * first. */
199   void FillBuffer (const TPixel& value);
200
201   /** \brief Set a pixel value.
202    *
203    * Allocate() needs to have been called first -- for efficiency,
204    * this function does not check that the image has actually been
205    * allocated yet. */
206   void SetPixel(const IndexType &index, const TPixel& value)
207     {
208     typename Superclass::OffsetValueType offset = this->ComputeOffset(index);
209     (*m_Buffer)[offset] = value;
210     }
211
212   /** \brief Get a pixel (read only version).
213    *
214    * For efficiency, this function does not check that the
215    * image has actually been allocated yet. */
216   const TPixel& GetPixel(const IndexType &index) const
217 IND **{
218     typename Superclass::OffsetValueType offset = this->ComputeOffset(index);
219     return ( (*m_Buffer)[offset] );
220 IND **}
221
222   /** \brief Get a reference to a pixel (e.g. for editing).
223    *
224    * For efficiency, this function does not check that the
225    * image has actually been allocated yet. */
226   TPixel& GetPixel(const IndexType &index)
227     {
228     typename Superclass::OffsetValueType offset = this->ComputeOffset(index);
229     return ( (*m_Buffer)[offset] );
230     }
231
232   /** \brief Access a pixel. This version can be an lvalue.
233    *
234    * For efficiency, this function does not check that the
235    * image has actually been allocated yet. */
236   TPixel & operator[](const IndexType &index)
237 IND *****{ return this->GetPixel(index); }
238
239   /** \brief Access a pixel. This version can only be an rvalue.
240    *
241    * For efficiency, this function does not check that the
242    * image has actually been allocated yet. */
243   const TPixel& operator[](const IndexType &index) const
244 IND *****{ return this->GetPixel(index); }
245
246   /** Return a pointer to the beginning of the buffer.  This is used by
247    * the image iterator class. */
248   TPixel *GetBufferPointer()
249     { return m_Buffer ? m_Buffer->GetBufferPointer() : 0; }
250   const TPixel *GetBufferPointer() const
251     { return m_Buffer ? m_Buffer->GetBufferPointer() : 0; }
252
253   /** Return a pointer to the container. */
254   PixelContainer* GetPixelContainer()
255     { return m_Buffer.GetPointer(); }
256
257   const PixelContainer* GetPixelContainer() const
258     { return m_Buffer.GetPointer(); }
259
260   /** Set the container to use. Note that this does not cause the
261    * DataObject to be modified. */
262   void SetPixelContainer( PixelContainer *container );
263
264   /** Return the Pixel Accessor object */
265   AccessorType GetPixelAccessor( void )
266     { return AccessorType(); }
267
268   /** Return the Pixel Accesor object */
269   const AccessorType GetPixelAccessor( void ) const
270     { return AccessorType(); }
271   
272   /** These functions do NOTHING!  They exist only to not break the pipeline.
273    * It is vital that the user specify any and all physical-spacing parameters
274    * to the output of a normal filter which is being used to output a
275    * special-coordinates image.  Filters designed to produce a particular kind
276    * of special-coordinates image should do this automatically. */
277   virtual void SetSpacing( const SpacingType ) {}
278   virtual void SetSpacing( const double [VImageDimension] ) {}
279   virtual void SetSpacing( const float [VImageDimension] ) {}
280   virtual void SetOrigin( const PointType ) {}
281   virtual void SetOrigin( const double [VImageDimension] ) {}
282   virtual void SetOrigin( const float [VImageDimension] ) {}
283   
284   /* It is ILLEGAL in C++ to make a templated member function virtual! */
285   /* Therefore, we must just let templates take care of everything.    */
286   /*
287   template<class TCoordRep>
288   virtual bool TransformPhysicalPointToContinuousIndex(
289               const Point<TCoordRep, VImageDimension>& point,
290               ContinuousIndex<TCoordRep, VImageDimension>& index   ) const = 0;
291   
292   template<class TCoordRep>
293   virtual bool TransformPhysicalPointToIndex(
294             const Point<TCoordRep, VImageDimension>&,
295             IndexType & index                                ) const = 0;
296
297   template<class TCoordRep>
298   virtual void TransformContinuousIndexToPhysicalPoint(
299             const ContinuousIndex<TCoordRep, VImageDimension>& index,
300             Point<TCoordRep, VImageDimension>& point        ) const = 0;
301
302   template<class TCoordRep>
303   virtual void TransformIndexToPhysicalPoint(
304                       const IndexType & index,
305                       Point<TCoordRep, VImageDimension>& point ) const = 0;
306   */
307
308 protected:
309   SpecialCoordinatesImage();
310   void PrintSelf(std::ostream& os, Indent indent) const;
311   virtual ~SpecialCoordinatesImage() {};
312 private:
313   SpecialCoordinatesImage(const Self&); //purposely not implemented
314   void operator=(const Self&); //purposely not implemented
315
316   /** Memory for the current buffer. */
317   PixelContainerPointer m_Buffer;
318 };
319 #ifdef ITK_EXPLICIT_INSTANTIATION
320 IND ***extern template class SpecialCoordinatesImage<float         ,2>;
321 IND ***extern template class SpecialCoordinatesImage<double        ,2>;
322 IND ***extern template class SpecialCoordinatesImage<unsigned char ,2>;
323 IND ***extern template class SpecialCoordinatesImage<unsigned short,2>;
324 IND ***extern template class SpecialCoordinatesImage<unsigned int  ,2>;
325 IND ***extern template class SpecialCoordinatesImage<signed char   ,2>;
326 IND ***extern template class SpecialCoordinatesImage<signed short  ,2>;
327 IND ***extern template class SpecialCoordinatesImage<signed int    ,2>;
328 IND ***extern template class SpecialCoordinatesImage<float         ,3>;
329 IND ***extern template class SpecialCoordinatesImage<double        ,3>;
330 IND ***extern template class SpecialCoordinatesImage<unsigned char ,3>;
331 IND ***extern template class SpecialCoordinatesImage<unsigned short,3>;
332 IND ***extern template class SpecialCoordinatesImage<unsigned int  ,3>;
333 IND ***extern template class SpecialCoordinatesImage<signed char   ,3>;
334 IND ***extern template class SpecialCoordinatesImage<signed short  ,3>;
335 IND ***extern template class SpecialCoordinatesImage<signed int    ,3>;
336 #endif
337 // end namespace itk
338 #ifndef ITK_MANUAL_INSTANTIATION
339 #include "itkSpecialCoordinatesImage.txx"
340 #endif
341
342 #endif
343
344 EOF

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