File: itkNarrowBandImageFilterBase.h

package info (click to toggle)
insighttoolkit4 4.13.3withdata-dfsg2-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 491,256 kB
  • sloc: cpp: 557,600; ansic: 180,546; fortran: 34,788; python: 16,572; sh: 2,187; lisp: 2,070; tcl: 993; java: 362; perl: 200; makefile: 133; csh: 81; pascal: 69; xml: 19; ruby: 10
file content (332 lines) | stat: -rw-r--r-- 12,080 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkNarrowBandImageFilterBase_h
#define itkNarrowBandImageFilterBase_h

#include "itkFiniteDifferenceImageFilter.h"
#include "itkMultiThreader.h"
#include "itkNarrowBand.h"
#include "itkBarrier.h"
#include "itkObjectStore.h"

namespace itk
{
/**
 * \class NarrowBandImageFilterBase
 *
 * \brief This class implements a multi-threaded finite difference
 *  image to image solver that can be applied to an arbitrary list of
 *  pixels.
 *
 * \par
 *  This class is intended as a common base class for classical narrowband
 *  solvers and manifold solvers. This base class implements a common
 *  memory management and multi-threaded architecture for applying a
 *  finite difference function to a list of pixels in an image. The specifics
 *  of narrowband solvers such as re-initialization and the use of land-mines
 *  are not implemented.
 *
 * \par INPUTS
 *  This filter takes an itk::Image as input.  The appropriate type of input
 *  image is entirely determined by the application.  As a rule, however, the
 *  input type is immediately converted to the output type before processing.
 *  This is because the input is not assumed to be a real value type and must be
 *  converted to signed, real values for the calculations.
 *
 * \par OUTPUTS
 *  The output is an itk::Image and is the solution of the pde.  The embedding of
 *  the interface may vary with the application, but the usual ITK convention is
 *  that it is the zero level set in the output image.
 *
 * \par IMPORTANT!
 *  Read the documentation for FiniteDifferenceImageFilter before attempting to
 *  use this filter.  The solver requires that you specify a
 *  FiniteDifferenceFunction to use for calculations.  This is set using the
 *  method SetDifferenceFunction in the parent class.
 *
 * \par REFERENCES
 * Sethian, J.A. Level Set Methods. Cambridge University Press. 1996.
 *
 * \ingroup ITKNarrowBand
 */
template< typename TInputImage, typename TOutputImage >
class ITK_TEMPLATE_EXPORT NarrowBandImageFilterBase:
  public FiniteDifferenceImageFilter< TInputImage, TOutputImage >
{
public:
  /** Standard class typedefs */
  typedef NarrowBandImageFilterBase                                Self;
  typedef FiniteDifferenceImageFilter< TInputImage, TOutputImage > Superclass;
  typedef SmartPointer< Self >                                     Pointer;
  typedef SmartPointer< const Self >                               ConstPointer;

  /** Run-time type information (and related methods) */
  itkTypeMacro(NarrowBandImageFilterBase, ImageToImageFilter);

  /**Typedefs from the superclass */
  typedef typename Superclass::InputImageType               InputImageType;
  typedef typename Superclass::OutputImageType              OutputImageType;
  typedef typename Superclass::FiniteDifferenceFunctionType FiniteDifferenceFunctionType;

  /** Dimensionality of input and output data is assumed to be the same.
   * It is inherited from the superclass. */
  itkStaticConstMacro(ImageDimension, unsigned int, Superclass::ImageDimension);

  /** The pixel type of the output image will be used in computations.
   * Inherited from the superclass. */
  typedef typename Superclass::PixelType PixelType;

  /** The value type of a time step.  Inherited from the superclass. */
  typedef typename Superclass::TimeStepType TimeStepType;

  /** The index type for the output image. */
  typedef typename OutputImageType::IndexType IndexType;

  /** The data type used in numerical computations.  Derived from the output
   *  image type. */
  typedef typename OutputImageType::ValueType ValueType;

  /** This is the storage type for the nodes on the narrow band. */
  typedef BandNode< IndexType, PixelType > BandNodeType;

  /** The list type for storing the narrow band. */
  typedef NarrowBand< BandNodeType >          NarrowBandType;
  typedef typename NarrowBandType::Pointer    NarrowBandPointer;
  typedef typename NarrowBandType::RegionType RegionType;
  typedef typename NarrowBandType::Iterator   NarrowBandIterator;

  /** Set/Get IsoSurfaceValue to use in the input image */
  itkSetMacro(IsoSurfaceValue, ValueType);
  itkGetConstMacro(IsoSurfaceValue, ValueType);

  /** Root Mean Square Change between successive iterations */
  //  itkGetConstMacro( RMSChange, ValueType);

  /** This function is used to insert a pixel index into the narrow band  The
   *   entire narrow band can be constructed using this method.  Usually,
   *   however, the narrow band is initialized and reinitialized automatically
   *   by the subclass. */
  void InsertNarrowBandNode(const BandNodeType & node)
  {
    m_NarrowBand->PushBack(node); // add new node
    this->Modified();
  }

  void InsertNarrowBandNode(const IndexType & index)
  {
    BandNodeType tmpnode;

    tmpnode.m_Index = index;
    m_NarrowBand->PushBack(tmpnode);
    this->Modified();
  }

  void InsertNarrowBandNode(const IndexType & index,
                            const PixelType & value,
                            const signed char & nodestate)
  {
    BandNodeType tmpnode;

    tmpnode.m_Data = value;
    tmpnode.m_Index = index;
    tmpnode.m_NodeState = nodestate;

    m_NarrowBand->PushBack(tmpnode);
    this->Modified();
  }

  /** Set the narrow band total radius. The narrow band width will be
   * twice this value (positive and negative distance to the zero level
   * set). The default value is 3. */
  void SetNarrowBandTotalRadius(const float& val)
  {
    if ( m_NarrowBand->GetTotalRadius() != val )
      {
      m_NarrowBand->SetTotalRadius(val);
      this->Modified();
      }
  }

  /** Get the narrow band total radius. */
  float GetNarrowBandTotalRadius() const
  {
    return m_NarrowBand->GetTotalRadius();
  }

  /** Set the narrow band inner radius. The inner radius is the safe
   * are where the level set can be computed. The default value is 1. */
  void SetNarrowBandInnerRadius(const float& val)
  {
    if ( m_NarrowBand->GetInnerRadius() != val )
      {
      m_NarrowBand->SetInnerRadius(val);
      this->Modified();
      }
  }

  /** Get the narrow band inner radius. */
  float GetNarrowBandInnerRadius() const
  {
    return m_NarrowBand->GetInnerRadius();
  }

  /** This is the virtual method called by Initialize to set the band of operation.
   *  It is left to the subclasses to define this functionality.
   *  This function can make use of above InsertNarrowBandNode function to create a
   *  band.
   */
  virtual void CreateNarrowBand(){}

  virtual void SetNarrowBand(NarrowBandType *ptr)
  {
    if ( m_NarrowBand != ptr )
      {
      m_NarrowBand = ptr;
      this->Modified();
      }
  }

  virtual void CopyInputToOutput() ITK_OVERRIDE;

protected:
  NarrowBandImageFilterBase()
  {
    m_NarrowBand = NarrowBandType::New();
    m_NarrowBand->SetTotalRadius(4);
    m_NarrowBand->SetInnerRadius(2);
    m_ReinitializationFrequency = 6;
    m_IsoSurfaceValue = 0.0;
    m_Step    = 0;
    m_Touched = false;
    m_Barrier = Barrier::New();
  }

  virtual ~NarrowBandImageFilterBase() ITK_OVERRIDE {}
  void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE;

  NarrowBandPointer m_NarrowBand;

  /** \struct ThreadRegionType
  The type of region used in multithreading.
  Defines a subregion of the narrowband. */
  struct ThreadRegionType {
    /** this is the actual first element */
    NarrowBandIterator first;

    /** this is one past the actual last element */
    NarrowBandIterator last;
  };

  /** A list of subregions of the narrowband which are passed to each thread
   * for parallel processing. */
  std::vector< RegionType > m_RegionList;

  /** This function returns a single region (of the narrow band list) for use
      in multi-threading */
  void GetSplitRegion(const size_t& i, ThreadRegionType & splitRegion);

  /** This function clears the existing narrow band, calls CreateNarrowBand to create
   *  a band, and calls the SplitRegions function of NarrowBand to pre-partition
   *  the band for multi-threading.
   */
  virtual void Initialize() ITK_OVERRIDE;

  /** This method check the narrow band state each iteration and reinitialize
      the narrow band if it is appropriate calling CreateNarrowBand and
      SplitRegions to pre-partion the band for multi-threading.
  */
  virtual void InitializeIteration() ITK_OVERRIDE;

  /** This method allows deallocation of data and further post processing
  */
  virtual void PostProcessOutput() ITK_OVERRIDE;

  /* This function clears all pixels from the narrow band */
  void ClearNarrowBand();

  /** Thread synchronization methods. */
  void WaitForAll();

  /** This is the default, high-level algorithm for calculating finite
    * difference solutions.  It calls virtual methods in its subclasses
    * to implement the major steps of the algorithm. */
  virtual void GenerateData() ITK_OVERRIDE;

  /* Variables to control reinitialization */
  IdentifierType m_ReinitializationFrequency;
  IdentifierType m_Step;

  bool m_Touched;

  std::vector< bool > m_TouchedForThread;

  ValueType m_IsoSurfaceValue;

  typename Barrier::Pointer m_Barrier;

private:
  ITK_DISALLOW_COPY_AND_ASSIGN(NarrowBandImageFilterBase);

  /** Structure for passing information into static callback methods.  Used in
   * the subclasses' threading mechanisms. */
  struct NarrowBandImageFilterBaseThreadStruct {
    NarrowBandImageFilterBase *Filter;
    TimeStepType TimeStep;
    std::vector< TimeStepType > TimeStepList;
    std::vector< bool > ValidTimeStepList;
  };

  /* This class does not use AllocateUpdateBuffer to allocate memory for its
   * narrow band. This is taken care of in SetNarrowBand, and InsertNarrowBandNode
   * functions. This function is here for compatibility with the
   * FiniteDifferenceSolver framework.
   */
  virtual void AllocateUpdateBuffer() ITK_OVERRIDE {}

  /** This method gives support for a multithread iterative scheme. */
  static ITK_THREAD_RETURN_TYPE IterateThreaderCallback(void *arg);

  /** This method is a thread implementation of the iterative scheme implemented
   * in itkFiniteDifferenceImageFilter::GenerateData. It relies on ThreadedApplyUpdate
   * and ThreadedCalculateChange to update the solution at every iteration. */
  virtual void ThreadedIterate(void *arg, ThreadIdType threadId);

  /** This method applies changes from the m_NarrowBand to the output using
   * the ThreadedApplyUpdate() method and a multithreading mechanism.  "dt" is
   * the time step to use for the update of each pixel. */
  virtual void ThreadedApplyUpdate(const TimeStepType& dt,
                                   const ThreadRegionType & regionToProcess,
                                   ThreadIdType threadId);

  virtual void ApplyUpdate(const TimeStepType&) ITK_OVERRIDE {}

  /** This method populates m_NarrowBand with changes for each pixel in the
   * output using the ThreadedCalculateChange() method and a multithreading
   * mechanism. Returns value is a time step to be used for the update. */
  virtual TimeStepType ThreadedCalculateChange(const ThreadRegionType & regionToProcess,
                                               ThreadIdType threadId);

  virtual TimeStepType CalculateChange() ITK_OVERRIDE { return 0; }
};
} // end namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
#include "itkNarrowBandImageFilterBase.hxx"
#endif

#endif