KWStyle - itkFiniteDifferenceImageFilter.h
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkFiniteDifferenceImageFilter.h.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:35 $
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 DEF #ifndef __itkFiniteDifferenceImageFilter_h_
18 DEF #define __itkFiniteDifferenceImageFilter_h_
19
20 #include "itkInPlaceImageFilter.h"
21 #include "itkFiniteDifferenceFunction.h"
22
23 namespace itk {
24
25 /**
26  * \class FiniteDifferenceImageFilter
27  *
28  * \par The Finite Difference Solver Hierarchy
29  *
30  * This is an overview of the finite difference solver (FDS) framework.  The
31  * FDS framework is a set of classes for creating filters to solve partial
32  * differential equations on images using an iterative, finite difference
33  * update scheme.
34  *
35  * \par
36  * The high-level algorithm implemented by the framework can be described by
37  * the following pseudocode.
38  *
39  * \code
40  *  WHILE NOT convergence:
41  *     FOR ALL pixels i
42  *        time_step = calculate_change(i)
43  *        update(i, time_step)
44  * \endcode
45  *
46  * \par
47  * The following equation describes update \f$n+1\f$ at pixel \f$i\f$ on
48  * discrete image \f$ u \f$ : 
49  *
50  * \par
51  * \f$u_{\mathbf{i}}^{n+1}=u^n_{\mathbf{i}}+\Delta u^n_{\mathbf{i}}\Delta t\f$
52  *
53  * \par Component objects
54  * The FDS hierarchy is comprised of two component object types, variations of
55  * which are designed to be plugged together to create filters for different
56  * applications.  At the process level are the ``solver'' objects, which are
57  * subclasses of FiniteDifferenceImageFilter.  Solver objects are filters that
58  * take image inputs and produce image outputs.  Solver objects require a
59  * ``finite difference function'' object to perform the calculation at each
60  * image pixel during iteration.  These specialized function objects are
61  * subclasses of FiniteDifferenceFunction. FiniteDifferenceFunctions take a
62  * neighborhood of pixels as input (in the form of an
63  * itk::NeighborhoodIterator) and produce a scalar valued result.
64  *
65  * \par
66  * Filters for different applications are created by defining a function object
67  * to handle the numerical calculations and choosing (or creating) a solver
68  * object that reflects the requirements and constraints of the application.
69  * For example, anisotropic diffusion filters are created by plugging
70  * anisotropic diffusion functions into the DenseFiniteDifferenceImageFilter.
71  * The separation between function object and solver object allows us to
72  * create, for example, sparse-field, dense-field, and narrow-band
73  * implementations of a level-set surface evolution filter can all be
74  * constructed by plugging the same function object into three different,
75  * specialized solvers.
76  *
77  * \par Creating new filters in this hierarchy
78  * The procedure for creating a filter within the FDS hierarchy is to identify
79  * all the virtual methods that need to be defined for your particular
80  * application.  In the simplest case, a filter needs only to instantiate a
81  * specific function object and define some halting criteria.  For more
82  * complicated applications, you may need to define a specialized type of
83  * iteration scheme or updating procedure in a higher-level solver object.
84  *
85  * \par
86  * Some simple examples are the specific subclasses of
87  * AnisotropicDiffusionImageFilter.  The leaves of the anisotropic diffusion
88  * filter tree only define the function object they use for their particular
89  * flavor of diffusion.  See CurvatureAnisotropicDiffusionImageFilter and
90  * GradientAnisotropicDiffusionImageFilter for details.    
91  *
92  * \par FiniteDifferenceImageFilter
93  * This class defines the generic solver API at the top level of the FDS
94  * framework. FiniteDifferenceImageFilter is an abstract class that implements
95  * the generic, high-level algorithm (described above). 
96  *
97  * \par Inputs and Outputs
98  * This filter is an Image to Image filter.  Depending on the specific
99  * subclass implementation, finite difference image filters may process a
100  * variety of image types.  The input to the filter is the initial
101  * value of \f$ u \f$ and the output of the filter is the solution to the
102  * p.d.e.
103  *
104  * \par How to use this class
105  * GenerateData() relies on several virtual methods that must be defined by a
106  * subclass.  Specifically: \em AllocateUpdateBuffer \em ApplyUpdate
107  * \em CalculateChange and \em Halt.  To create a finite difference solver,
108  * implement a subclass to define these methods.
109  *
110  * \par
111  * Note that there is no fixed container type for the buffer used to hold
112  * the update \f$ \Delta \f$.  The container might be another image, or simply
113  * a list of values.  AllocateUpdateBuffer is responsible for creating the
114  * \f$ \Delta \f$ container.  CalculateChange populates this buffer and
115  * ApplyUpdate adds the buffer values to the output image (solution).  The
116 LEN  * boolean Halt() (or ThreadedHalt) method returns a true value to stop iteration.
117  *
118  * \ingroup ImageFilter
119  * \ingroup LevelSetSegmentation
120  * \sa DenseFiniteDifferenceImageFilter */
121 template <class TInputImage, class TOutputImage>
122 class ITK_EXPORT FiniteDifferenceImageFilter  
123 IND **: public InPlaceImageFilter<TInputImage, TOutputImage>
124 {
125 public:
126   /** Standard class typedefs. */
127   typedef FiniteDifferenceImageFilter Self;
128 TDA   typedef InPlaceImageFilter<TInputImage, TOutputImage> Superclass;
129 TDA   typedef SmartPointer<Self>  Pointer;
130 TDA   typedef SmartPointer<const Self>  ConstPointer;
131   
132   /** Run-time type information (and related methods) */
133   itkTypeMacro(FiniteDifferenceImageFilter, InPlaceImageFilter );
134   
135   /** Input and output image types. */
136   typedef TInputImage  InputImageType;
137   typedef TOutputImage OutputImageType;
138   
139   /** Dimensionality of input and output data is assumed to be the same. */
140   itkStaticConstMacro(ImageDimension, unsigned int,
141                       OutputImageType::ImageDimension);
142
143   /** The pixel type of the output image will be used in computations. */
144   typedef typename TOutputImage::PixelType PixelType;
145
146   /** The value type of the time step.  This is distinct from PixelType
147    * because PixelType may often be a vector value, while the TimeStep is
148    * a scalar value. */
149   typedef FiniteDifferenceFunction<TOutputImage> FiniteDifferenceFunctionType;
150 TDA   typedef typename FiniteDifferenceFunctionType::TimeStepType TimeStepType;
151
152   typedef enum { UNINITIALIZED = 0, INITIALIZED = 1 } FilterStateType;
153   
154   /** Get the number of elapsed iterations of the filter. */
155   itkGetConstReferenceMacro(ElapsedIterations, unsigned int);
156
157   /** This method returns a pointer to a FiniteDifferenceFunction object that
158    * will be used by the filter to calculate updates at image pixels.
159    * \returns A FiniteDifferenceObject pointer. */
160   itkGetConstReferenceObjectMacro(DifferenceFunction,
161                                   FiniteDifferenceFunctionType );
162
163   /** This method sets the pointer to a FiniteDifferenceFunction object that
164    * will be used by the filter to calculate updates at image pixels.
165    * \returns A FiniteDifferenceObject pointer. */
166   itkSetObjectMacro(DifferenceFunction, FiniteDifferenceFunctionType );
167
168
169 IND */** Set/Get the number of iterations that the filter will run. */
170   itkSetMacro(NumberOfIterations, unsigned int);
171   itkGetConstReferenceMacro(NumberOfIterations, unsigned int);
172
173   /** Use the image spacing information in calculations. Use this option if you
174    *  want derivatives in physical space. Default is UseImageSpacingOff. */
175   itkSetMacro(UseImageSpacing,bool);
176   itkBooleanMacro(UseImageSpacing);
177   itkGetConstReferenceMacro(UseImageSpacing, bool);
178
179   /** Set/Get the maximum error allowed in the solution.  This may not be
180 LEN,IND ******defined for all solvers and its meaning may change with the application. */
181   itkSetMacro(MaximumRMSError, double);
182   itkGetConstReferenceMacro(MaximumRMSError, double);
183
184   /** Set/Get the root mean squared change of the previous iteration. May not
185 IND ******be used by all solvers. */
186   itkSetMacro(RMSChange, double);
187   itkGetConstReferenceMacro(RMSChange, double);
188
189   /** Set the state of the filter to INITIALIZED */
190   void SetStateToInitialized()
191 IND **{
192     this->SetState(INITIALIZED);
193 IND **}
194
195   /** Set the state of the filter to UNINITIALIZED */
196   void SetStateToUninitialized()
197 IND **{
198     this->SetState(UNINITIALIZED);
199 IND **}
200   
201   /** Set/Get the state of the filter. */
202   itkSetMacro(State, FilterStateType);
203   itkGetConstReferenceMacro(State, FilterStateType);
204
205   /** Require the filter to be manually reinitialized (by calling
206       SetStateToUninitialized() */
207   itkSetMacro(ManualReinitialization, bool);
208   itkGetConstReferenceMacro(ManualReinitialization, bool);
209   itkBooleanMacro(ManualReinitialization);
210   
211 protected:
212   FiniteDifferenceImageFilter()
213 IND **{
214     m_UseImageSpacing    = false;
215     m_ElapsedIterations  = 0;
216     m_DifferenceFunction = 0;
217     m_NumberOfIterations = NumericTraits<unsigned int>::max();
218     m_MaximumRMSError = 0.0;
219     m_RMSChange = 0.0;
220     m_State = UNINITIALIZED;
221     m_ManualReinitialization = false;
222     this->InPlaceOff();
223 IND **}
224   ~FiniteDifferenceImageFilter() {}
225   void PrintSelf(std::ostream& os, Indent indent) const;
226
227   /** This method allocates a temporary update container in the subclass. */
228   virtual void AllocateUpdateBuffer() = 0;
229
230   /** This method is defined by a subclass to apply changes to the output
231    * from an update buffer and a time step value "dt".
232    * \param dt Time step value. */
233   virtual void ApplyUpdate(TimeStepType dt) = 0;
234   
235   /** This method is defined by a subclass to populate an update buffer
236    * with changes for the pixels in the output.  It returns a time
237    * step value to be used for the update.
238    * \returns A time step to use in updating the output with the changes
239    * calculated from this method. */
240   virtual TimeStepType CalculateChange() = 0;
241
242   /** This method can be defined in subclasses as needed to copy the input
243    * to the output. See DenseFiniteDifferenceImageFilter for an
244    * implementation. */
245   virtual void CopyInputToOutput() = 0;
246   
247   /** This is the default, high-level algorithm for calculating finite
248    * difference solutions.  It calls virtual methods in its subclasses
249    * to implement the major steps of the algorithm. */
250   virtual void GenerateData();
251
252   /** FiniteDifferenceImageFilter needs a larger input requested region than
253    * the output requested region.  As such, we need to provide
254    * an implementation for GenerateInputRequestedRegion() in order to inform
255    * the pipeline execution model.
256    *
257    * \par
258    * The filter will ask for a padded region to perform its neighborhood
259    * calculations.  If no such region is available, the boundaries will be
260    * handled as described in the FiniteDifferenceFunction defined by the
261    * subclass.
262    * \sa ProcessObject::GenerateInputRequestedRegion() */
263   virtual void GenerateInputRequestedRegion();
264   
265   /** This method returns true when the current iterative solution of the
266    * equation has met the criteria to stop solving.  Defined by a subclass. */
267   virtual bool Halt();
268
269   /** This method is similar to Halt(), and its default implementation in this
270    * class is simply to call Halt(). However, this method takes as a parameter
271    * a void pointer to the MultiThreader::ThreadInfoStruct structure. If you
272    * override this method instead of overriding Halt, you will be able to get
273 LEN    * the current thread ID and handle the Halt method accordingly. This is useful
274 LEN    * if you are doing a lot of processing in Halt that you don't want parallelized.
275 LEN    * Notice that ThreadedHalt is only called by the multithreaded filters, so you
276    * still should implement Halt, just in case a non-threaded filter is used.
277    */
278 LEN   virtual bool ThreadedHalt(void *itkNotUsed(threadInfo)) { return this->Halt(); }
279
280   /** This method is optionally defined by a subclass and is called before
281    * the loop of iterations of calculate_change & upate. It does the global
282    * initialization, i.e. in the SparseFieldLevelSetImageFilter, initialize 
283    * the list of layers. 
284    * */
285   virtual void Initialize() { };
286
287   /** This method is optionally defined by a subclass and is called immediately
288    * prior to each iterative CalculateChange-ApplyUpdate cycle.  It can be
289    * used to set global variables needed for the next iteration (ie. average
290    * gradient magnitude of the image in anisotropic diffusion functions), or
291    * otherwise prepare for the next iteration.
292    * */
293   virtual void InitializeIteration()
294     { m_DifferenceFunction->InitializeIteration(); }
295   
296   /** Virtual method for resolving a single time step from a set of time steps
297    * returned from processing threads.
298    * \return Time step (dt) for the iteration update based on a list
299    * of time steps generated from the threaded calculated change method (one
300    * for each region processed).
301    *
302 LEN    * \param timeStepList The set of time changes compiled from all the threaded calls
303    * to ThreadedGenerateData.
304    * \param valid The set of flags indicating which of "list" elements are
305    *  valid
306    * \param size The size of "list" and "valid"
307    *
308    * The default is to return the minimum value in the list. */
309   virtual TimeStepType ResolveTimeStep(const TimeStepType* timeStepList, 
310                                        const bool* valid,int size);
311
312   /** Set the number of elapsed iterations of the filter. */
313   itkSetMacro(ElapsedIterations, unsigned int);
314
315   /** This method is called after the solution has been generated to allow
316    * subclasses to apply some further processing to the output.*/
317   virtual void PostProcessOutput() {}
318
319   /** The maximum number of iterations this filter will run */
320   unsigned int  m_NumberOfIterations;
321
322   double m_RMSChange;  
323   double m_MaximumRMSError;
324
325 private:
326   FiniteDifferenceImageFilter(const Self&); //purposely not implemented
327   void operator=(const Self&); //purposely not implemented
328
329   /** A counter for keeping track of the number of elapsed 
330 IND ******iterations during filtering. */
331   unsigned int m_ElapsedIterations;
332
333   /** Control whether derivatives use spacing of the input image in
334 IND ******its calculation. */
335   bool m_UseImageSpacing;
336
337   /** Indicates whether the filter automatically resets to UNINITIALIZED state
338 IND ******after completing, or whether filter must be manually reset */
339   bool m_ManualReinitialization;
340   
341   /** The function that will be used in calculating updates for each pixel. */
342   typename FiniteDifferenceFunctionType::Pointer m_DifferenceFunction;
343
344   /** State that the filter is in, i.e. UNINITIALIZED or INITIALIZED */
345   FilterStateType m_State;
346 };
347   
348 }// end namespace itk
349
350 #ifndef ITK_MANUAL_INSTANTIATION
351 #include "itkFiniteDifferenceImageFilter.txx"
352 #endif
353
354 #endif
355
356 EOF

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