File: itkFastMarchingBase.h

package info (click to toggle)
insighttoolkit5 5.4.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 704,588 kB
  • sloc: cpp: 784,579; ansic: 628,724; xml: 44,704; fortran: 34,250; python: 22,934; sh: 4,078; pascal: 2,636; lisp: 2,158; makefile: 461; yacc: 328; asm: 205; perl: 203; lex: 146; tcl: 132; javascript: 98; csh: 81
file content (334 lines) | stat: -rw-r--r-- 11,729 bytes parent folder | download | duplicates (2)
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
333
334
/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  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
 *
 *         https://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 itkFastMarchingBase_h
#define itkFastMarchingBase_h

#include "itkIntTypes.h"
#include "itkFastMarchingStoppingCriterionBase.h"
#include "itkFastMarchingTraits.h"
#include "ITKFastMarchingExport.h"

#include <queue>
#include <functional>

namespace itk
{
/**
 * \class FastMarchingTraitsEnums
 * \ingroup ITKFastMarching
 * */
class FastMarchingTraitsEnums
{
public:
  /**
   * \class TopologyCheck
   * \ingroup ITKFastMarching
   * */
  enum class TopologyCheck : uint8_t
  {
    Nothing = 0,
    NoHandles,
    Strict
  };
};
// Define how to print enumeration
extern ITKFastMarching_EXPORT std::ostream &
                              operator<<(std::ostream & out, const FastMarchingTraitsEnums::TopologyCheck value);

/**
 * \class FastMarchingBase
 * \brief Abstract class to solve an Eikonal based-equation using Fast Marching
 * Method.
 *
 * Fast marching solves an Eikonal equation where the speed is always
 * non-negative and depends on the position only. Starting from an
 * initial position on the front, fast marching systematically moves the
 * front forward one node at a time.
 *
 * Updates are performed using an entropy satisfy scheme where only
 * "upwind" neighborhoods are used. This implementation of Fast Marching
 * uses a std::priority_queue to locate the next proper node to
 * update.
 *
 * Fast Marching sweeps through N points in (N log N) steps to obtain
 * the arrival time value as the front propagates through the domain.
 *
 * The initial front is specified by two containers:
 * \li one containing the known nodes (Alive Nodes: nodes that are already
 * part of the object),
 * \li one containing the trial nodes (Trial Nodes: nodes that are
 * considered for inclusion).
 *
 * In order for the filter to evolve, at least some trial nodes must be
 * specified. These can for instance be specified as the layer of
 * nodes around the alive ones.
 *
 * The algorithm is terminated early by setting an appropriate stopping
 * criterion, or if there are no more nodes to process.
 *
 * \tparam TTraits traits which includes definition such as:
 *    \li InputDomainType (itk::Image or itk::QuadEdgeMesh)
 *    \li OutputDomainType (similar to InputDomainType)
 *    \li NodeType (itk::Index if itk::Image and PointIdentifier if
 * itk::QuadEdgeMesh)
 *    \li NodePairType std::pair< NodeType, OutputPixelType >
 *    \li Superclass (itk::ImageToImageFilter or
 * itk::QuadEdgeMeshToQuadEdgeMeshFilter )
 *
 * \todo In the current implementation, std::priority_queue only allows
 * taking nodes out from the front and putting nodes in from the back.
 * Use itk::PriorityQueueContainer instead.
 *
 * \par Topology constraints:
 * Additional flexibility in this class includes the implementation of
 * topology constraints for image-based fast marching.  Further details
 * can be found in the paper
 *
 * NJ Tustison, BA Avants, MF Siqueira, JC Gee. "Topological Well-
 * Composedness and Glamorous Glue: A Digital Gluing Algorithm for
 * Topologically Constrained Front Propagation, IEEE Transactions on
 * Image Processing, 20(6):1756-1761, June 2011.
 *
 * Essentially, one can constrain the propagating front(s) such that
 * they either:
 *  1. don't merge (using the "Strict" option)
 *  2. don't create handles (using the "NoHandles" option)
 *
 * Whereas the majority of related work uses the digital topological
 * concept of "simple points" to constrain the evolving front, this
 * filter uses the concept of "well-composedness".  Advantages of
 * the latter over the former includes being able to use the standard
 * marching cubes algorithm to produce a mesh whose genus is identical
 * to that of the evolved front(s).
 *
 * \sa FastMarchingStoppingCriterionBase
 *
 * \ingroup ITKFastMarching
 */
template <typename TInput, typename TOutput>
class ITK_TEMPLATE_EXPORT FastMarchingBase : public FastMarchingTraits<TInput, TOutput>::SuperclassType
{
public:
  ITK_DISALLOW_COPY_AND_MOVE(FastMarchingBase);

  using Traits = FastMarchingTraits<TInput, TOutput>;
  using SuperclassType = typename Traits::SuperclassType;

  using Self = FastMarchingBase;
  using Superclass = typename FastMarchingTraits<TInput, TOutput>::SuperclassType;
  using Pointer = SmartPointer<Self>;
  using ConstPointer = SmartPointer<const Self>;

  /** \see LightObject::GetNameOfClass() */
  itkOverrideGetNameOfClassMacro(FastMarchingBase);

  /** Input Domain related definitions */
  using InputDomainType = typename Traits::InputDomainType;
  using InputDomainPointer = typename Traits::InputDomainPointer;
  using InputPixelType = typename Traits::InputPixelType;

  /** Output Domain related definitions */
  using OutputDomainType = typename Traits::OutputDomainType;
  using OutputDomainPointer = typename Traits::OutputDomainPointer;
  using OutputPixelType = typename Traits::OutputPixelType;

  /** NodeType type of node */
  using NodeType = typename Traits::NodeType;

  /** NodePairType pair of node and corresponding value */
  using NodePairType = typename Traits::NodePairType;
  using NodePairContainerType = typename Traits::NodePairContainerType;
  using NodePairContainerPointer = typename Traits::NodePairContainerPointer;
  using NodePairContainerConstIterator = typename Traits::NodePairContainerConstIterator;

  using LabelType = typename Traits::LabelType;

  /** StoppingCriterionType stopping criterion */
  using StoppingCriterionType = FastMarchingStoppingCriterionBase<TInput, TOutput>;
  using StoppingCriterionPointer = typename StoppingCriterionType::Pointer;

  /*
  using ElementIdentifier = long;

  using PriorityQueueElementType = MinPriorityQueueElementWrapper< NodeType,
    OutputPixelType,
    ElementIdentifier >;

  using PriorityQueueType = PriorityQueueContainer< PriorityQueueElementType,
    PriorityQueueElementType, OutputPixelType, ElementIdentifier >;
  using PriorityQueuePointer = typename PriorityQueueType::Pointer;
  */

  using TopologyCheckEnum = FastMarchingTraitsEnums::TopologyCheck;
#if !defined(ITK_LEGACY_REMOVE)
  using TopologyCheckType = FastMarchingTraitsEnums::TopologyCheck;
  /**Exposes enums values for backwards compatibility*/
  static constexpr TopologyCheckEnum Nothing = TopologyCheckEnum::Nothing;
  static constexpr TopologyCheckEnum NoHandles = TopologyCheckEnum::NoHandles;
  static constexpr TopologyCheckEnum Strict = TopologyCheckEnum::Strict;
#endif

  /** Set/Get the TopologyCheckType macro indicating whether the user
  wants to check topology (and which one). */
  itkSetEnumMacro(TopologyCheck, TopologyCheckEnum);
  itkGetConstReferenceMacro(TopologyCheck, TopologyCheckEnum);

  /** Set/Get TrialPoints */
  itkSetObjectMacro(TrialPoints, NodePairContainerType);
  itkGetModifiableObjectMacro(TrialPoints, NodePairContainerType);

  /** Set/Get AlivePoints */
  itkSetObjectMacro(AlivePoints, NodePairContainerType);
  itkGetModifiableObjectMacro(AlivePoints, NodePairContainerType);

  /** Set/Get ProcessedPoints */
  itkSetObjectMacro(ProcessedPoints, NodePairContainerType);
  itkGetModifiableObjectMacro(ProcessedPoints, NodePairContainerType);

  /** Set/Get ForbiddenPoints */
  itkSetObjectMacro(ForbiddenPoints, NodePairContainerType);
  itkGetModifiableObjectMacro(ForbiddenPoints, NodePairContainerType);

  /** \brief Set/Get the Stopping Criterion */
  itkSetObjectMacro(StoppingCriterion, StoppingCriterionType);
  itkGetModifiableObjectMacro(StoppingCriterion, StoppingCriterionType);

  /** \brief Set/Get SpeedConstant */
  itkGetMacro(SpeedConstant, double);
  itkSetMacro(SpeedConstant, double);

  /** \brief Set/Get NormalizationFactor */
  itkGetMacro(NormalizationFactor, double);
  itkSetMacro(NormalizationFactor, double);

  /** \brief Get the value reached by the front when it stops propagating */
  itkGetMacro(TargetReachedValue, OutputPixelType);

  /** Set the Collect Points flag. Instrument the algorithm to collect
   * a container of all nodes which it has visited. Useful for
   * creating Narrowbands for level set algorithms that supports
   * narrow banding. */
  itkSetMacro(CollectPoints, bool);

  /** Get the Collect Points flag. */
  itkGetConstReferenceMacro(CollectPoints, bool);
  itkBooleanMacro(CollectPoints);

protected:
  /** \brief Constructor */
  FastMarchingBase();

  /** \brief Destructor */
  ~FastMarchingBase() override = default;

  StoppingCriterionPointer m_StoppingCriterion{};

  double m_SpeedConstant{};
  double m_InverseSpeed{};
  double m_NormalizationFactor{};

  OutputPixelType m_TargetReachedValue{};
  OutputPixelType m_LargeValue{};
  OutputPixelType m_TopologyValue{};

  NodePairContainerPointer m_TrialPoints{};
  NodePairContainerPointer m_AlivePoints{};
  NodePairContainerPointer m_ProcessedPoints{};
  NodePairContainerPointer m_ForbiddenPoints{};

  bool m_CollectPoints{};

  // PriorityQueuePointer m_Heap;
  using HeapContainerType = std::vector<NodePairType>;
  using NodeComparerType = std::greater<NodePairType>;

  using PriorityQueueType = std::priority_queue<NodePairType, HeapContainerType, NodeComparerType>;

  PriorityQueueType m_Heap{};

  TopologyCheckEnum m_TopologyCheck{};

  /** \brief Get the total number of nodes in the domain */
  virtual IdentifierType
  GetTotalNumberOfNodes() const = 0;

  /** \brief Get the output value (front value) for a given node */
  virtual const OutputPixelType
  GetOutputValue(OutputDomainType * oDomain, const NodeType & iNode) const = 0;

  /** \brief Set the output value (front value) for a given node */
  virtual void
  SetOutputValue(OutputDomainType * oDomain, const NodeType & iNode, const OutputPixelType & iValue) = 0;

  /** \brief Get the LabelEnum Value for a given node
    \param[in] iNode
    \return its label value  */
  virtual unsigned char
  GetLabelValueForGivenNode(const NodeType & iNode) const = 0;

  /** \brief Set the Label Value for a given node
    \param[in] iNode
    \param[in] iLabel */
  virtual void
  SetLabelValueForGivenNode(const NodeType & iNode, const LabelType & iLabel) = 0;

  /** \brief Update neighbors to a given node
    \param[in] oDomain
    \param[in] iNode
  */
  virtual void
  UpdateNeighbors(OutputDomainType * oDomain, const NodeType & iNode) = 0;

  /** \brief Update value for a given node
    \param[in] oDomain
    \param[in] iNode
    */
  virtual void
  UpdateValue(OutputDomainType * oDomain, const NodeType & iNode) = 0;

  /** \brief Check if the current node violate topological criterion.
    \param[in] oDomain
    \param[in] iNode
   */
  virtual bool
  CheckTopology(OutputDomainType * oDomain, const NodeType & iNode) = 0;

  /** \brief   */
  void
  Initialize(OutputDomainType * oDomain);

  /**    */
  virtual void
  InitializeOutput(OutputDomainType * oDomain) = 0;

  /**    */
  void
  GenerateData() override;

  /** \brief PrintSelf method  */
  void
  PrintSelf(std::ostream & os, Indent indent) const override;
};
} // namespace itk

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

#endif