ITK  5.1.0
Insight Toolkit
itkContourExtractor2DImageFilter.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright NumFOCUS
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkContourExtractor2DImageFilter_h
19 #define itkContourExtractor2DImageFilter_h
20 
21 #include "itkImageToPathFilter.h"
23 #include "itkConceptChecking.h"
24 #include <unordered_map>
25 #include <deque>
26 #include <list>
27 
28 namespace itk
29 {
97 
98 template <typename TInputImage>
99 class ITK_TEMPLATE_EXPORT ContourExtractor2DImageFilter
100  : public ImageToPathFilter<TInputImage, PolyLineParametricPath<2>>
101 {
102 public:
103  ITK_DISALLOW_COPY_AND_ASSIGN(ContourExtractor2DImageFilter);
104 
106  static constexpr unsigned int InputImageDimension = TInputImage::ImageDimension;
107 
109  using InputImageType = TInputImage;
111 
117 
119  itkNewMacro(Self);
120 
123 
125  using InputImagePointer = typename InputImageType::Pointer;
126  using InputPixelType = typename InputImageType::PixelType;
128  using InputOffsetType = typename InputImageType::OffsetType;
133 
136 
137  using VertexListConstPointer = typename VertexListType::ConstPointer;
138 
141  itkSetMacro(ReverseContourOrientation, bool);
142  itkGetConstReferenceMacro(ReverseContourOrientation, bool);
143  itkBooleanMacro(ReverseContourOrientation);
145 
149  itkSetMacro(VertexConnectHighPixels, bool);
150  itkGetConstReferenceMacro(VertexConnectHighPixels, bool);
151  itkBooleanMacro(VertexConnectHighPixels);
153 
156  void
157  SetRequestedRegion(const InputRegionType region);
158 
159  itkGetConstReferenceMacro(RequestedRegion, InputRegionType);
160  void
161  ClearRequestedRegion();
162 
165  itkSetMacro(ContourValue, InputRealType);
166  itkGetConstReferenceMacro(ContourValue, InputRealType);
168 
169 #ifdef ITK_USE_CONCEPT_CHECKING
170  // Begin concept checking
172  itkConceptMacro(InputPixelTypeComparable, (Concept::Comparable<InputPixelType>));
173  itkConceptMacro(InputHasPixelTraitsCheck, (Concept::HasPixelTraits<InputPixelType>));
174  itkConceptMacro(InputHasNumericTraitsCheck, (Concept::HasNumericTraits<InputPixelType>));
175  // End concept checking
176 #endif
177 
178 protected:
180  ~ContourExtractor2DImageFilter() override = default;
181  void
182  PrintSelf(std::ostream & os, Indent indent) const override;
183 
184  void
185  GenerateData() override;
186 
190  void
191  GenerateInputRequestedRegion() override;
192 
193 private:
194  VertexType
195  InterpolateContourPosition(InputPixelType fromValue,
196  InputPixelType toValue,
197  InputIndexType fromIndex,
198  InputOffsetType toOffset);
199 
200  void
201  AddSegment(const VertexType from, const VertexType to);
202 
203  void
204  FillOutputs();
205 
212 
213  // Represent each contour as deque of vertices to facilitate addition of
214  // nodes at beginning or end. At the end of the processing, we will copy
215  // the contour into a PolyLineParametricPath.
216  // We subclass the deque to store an additional bit of information: an
217  // identification number for each growing contour. We use this number so
218  // that when it becomes necessary to merge two growing contours, we can
219  // merge the newer one into the older one. This helps because then we can
220  // guarantee that the output contour list is ordered from left to right,
221  // top to bottom (in terms of the first pixel of the contour encountered
222  // by the marching squares). Currently we make no guarantees that this
223  // pixel is the first pixel in the contour list, just that the contours
224  // are so ordered in the output. Ensuring this latter condition (first
225  // pixel traversed = first pixel in contour) would be possible by either
226  // changing the merging rules, which would make the contouring operation
227  // slower, or by storing additional data as to which pixel was first.
228  class ContourType : public std::deque<VertexType>
229  {
230  public:
231  unsigned int m_ContourNumber;
232  };
233 
234  // Store all the growing contours in a list. We may need to delete contours
235  // from anywhere in the sequence (when we merge them together), so we need to
236  // use a list instead of a vector or similar.
237  using ContourContainer = std::list<ContourType>;
238  using ContourRef = typename ContourContainer::iterator;
239 
240  // declare the hash function we are using for the hash_map.
241  struct VertexHash
242  {
243  using CoordinateType = typename VertexType::CoordRepType;
244  inline SizeValueType
245  operator()(const VertexType & k) const
246  {
247  // Xor the hashes of the vertices together, after multiplying the
248  // first by some number, so that identical (x,y) vertex indices
249  // don't all hash to the same bucket. This is a decent if not
250  // optimal hash.
251  const SizeValueType hashVertex1 = this->float_hash(k[0] * 0xbeef);
252  const SizeValueType hashVertex2 = this->float_hash(k[1]);
253  const SizeValueType hashValue = hashVertex1 ^ hashVertex2;
254 
255  return hashValue;
256  }
257 
258  // Define hash function for floats. Based on method from
259  // http://www.brpreiss.com/books/opus4/html/page217.html
260  inline SizeValueType
261  float_hash(const CoordinateType & k) const
262  {
263  if (k == 0)
264  {
265  return 0;
266  }
267  int exponent;
268  CoordinateType mantissa = std::frexp(k, &exponent);
269  auto value = static_cast<SizeValueType>(std::fabs(mantissa));
270  value = (2 * value - 1) * ~0U;
271  return value;
272  }
273  };
274 
275  // We use a hash to associate the endpoints of each contour with the
276  // contour itself. This makes it easy to look up which contour we should add
277  // a new arc to.
278  // We can't store the contours themselves in the hashtable because we
279  // need to have two tables (one to hash from beginpoint -> contour and one
280  // for endpoint -> contour), and sometimes will remove a contour from the
281  // tables (if it has been closed or merged with another contour). So in the
282  // hash table we store a reference to the contour. Because sometimes we will
283  // need to merge contours, we need to be able to quickly remove contours
284  // from our list when they have been merged into another. Thus, we store
285  // an iterator pointing to the contour in the list.
286 
287  using VertexToContourMap = std::unordered_map<VertexType, ContourRef, VertexHash>;
288  using VertexMapIterator = typename VertexToContourMap::iterator;
289  using VertexContourRefPair = typename VertexToContourMap::value_type;
290 
291  // The contours we find in the image are stored here
293 
294  // And indexed by their beginning and ending points here
297 };
298 } // end namespace itk
299 
300 #ifndef ITK_MANUAL_INSTANTIATION
301 # include "itkContourExtractor2DImageFilter.hxx"
302 #endif
303 
304 #endif
itk::ContourExtractor2DImageFilter::VertexHash::CoordinateType
typename VertexType::CoordRepType CoordinateType
Definition: itkContourExtractor2DImageFilter.h:243
itk::Concept::HasNumericTraits
Definition: itkConceptChecking.h:712
itk::ContourExtractor2DImageFilter::VertexContourRefPair
typename VertexToContourMap::value_type VertexContourRefPair
Definition: itkContourExtractor2DImageFilter.h:289
itk::ContourExtractor2DImageFilter
Computes a list of PolyLineParametricPath objects from the contours in a 2D image.
Definition: itkContourExtractor2DImageFilter.h:99
itkImageToPathFilter.h
itk::ContourExtractor2DImageFilter::m_ReverseContourOrientation
bool m_ReverseContourOrientation
Definition: itkContourExtractor2DImageFilter.h:207
itk::ContourExtractor2DImageFilter::InputIndexType
typename InputImageType::IndexType InputIndexType
Definition: itkContourExtractor2DImageFilter.h:127
itk::ContourExtractor2DImageFilter::VertexListType
typename OutputPathType::VertexListType VertexListType
Definition: itkContourExtractor2DImageFilter.h:132
itkConceptChecking.h
itk::ContourExtractor2DImageFilter::ContourType::m_ContourNumber
unsigned int m_ContourNumber
Definition: itkContourExtractor2DImageFilter.h:231
itk::ContourExtractor2DImageFilter::m_Contours
ContourContainer m_Contours
Definition: itkContourExtractor2DImageFilter.h:292
itk::ContourExtractor2DImageFilter::m_NumberOfContoursCreated
unsigned int m_NumberOfContoursCreated
Definition: itkContourExtractor2DImageFilter.h:211
itk::SmartPointer< Self >
itk::Indent
Control indentation during Print() invocation.
Definition: itkIndent.h:49
itk::ContourExtractor2DImageFilter::ContourRef
typename ContourContainer::iterator ContourRef
Definition: itkContourExtractor2DImageFilter.h:238
itk::ContourExtractor2DImageFilter::m_ContourValue
InputRealType m_ContourValue
Definition: itkContourExtractor2DImageFilter.h:206
itk::ContourExtractor2DImageFilter::OutputPathPointer
typename OutputPathType::Pointer OutputPathPointer
Definition: itkContourExtractor2DImageFilter.h:130
itk::Concept::SameDimension
Definition: itkConceptChecking.h:692
itk::ImageToPathFilter
Base class for filters that take an image as input and produce an path as output.
Definition: itkImageToPathFilter.h:44
itk::ContourExtractor2DImageFilter::ContourContainer
std::list< ContourType > ContourContainer
Definition: itkContourExtractor2DImageFilter.h:237
itk::GTest::TypedefsAndConstructors::Dimension2::IndexType
ImageBaseType::IndexType IndexType
Definition: itkGTestTypedefsAndConstructors.h:50
itk::LightObject
Light weight base class for most itk classes.
Definition: itkLightObject.h:59
itk::PolyLineParametricPath
Represent a path of line segments through ND Space.
Definition: itkPolyLineParametricPath.h:57
itk::ContourExtractor2DImageFilter::InputRegionType
typename InputImageType::RegionType InputRegionType
Definition: itkContourExtractor2DImageFilter.h:129
itk::ContourExtractor2DImageFilter::InputImagePointer
typename InputImageType::Pointer InputImagePointer
Definition: itkContourExtractor2DImageFilter.h:125
itk::ContourExtractor2DImageFilter::m_ContourStarts
VertexToContourMap m_ContourStarts
Definition: itkContourExtractor2DImageFilter.h:295
itk::GTest::TypedefsAndConstructors::Dimension2::RegionType
ImageBaseType::RegionType RegionType
Definition: itkGTestTypedefsAndConstructors.h:54
itk::ContourExtractor2DImageFilter::VertexMapIterator
typename VertexToContourMap::iterator VertexMapIterator
Definition: itkContourExtractor2DImageFilter.h:288
itk::ContourExtractor2DImageFilter::m_UseCustomRegion
bool m_UseCustomRegion
Definition: itkContourExtractor2DImageFilter.h:209
itk::ContourExtractor2DImageFilter::m_ContourEnds
VertexToContourMap m_ContourEnds
Definition: itkContourExtractor2DImageFilter.h:296
itk::ContourExtractor2DImageFilter::VertexListConstPointer
typename VertexListType::ConstPointer VertexListConstPointer
Definition: itkContourExtractor2DImageFilter.h:137
itk::Concept::Comparable
Definition: itkConceptChecking.h:328
itk::NumericTraits
Define additional traits for native types such as int or float.
Definition: itkNumericTraits.h:58
itk::ContourExtractor2DImageFilter::m_RequestedRegion
InputRegionType m_RequestedRegion
Definition: itkContourExtractor2DImageFilter.h:210
itk::ContourExtractor2DImageFilter::VertexToContourMap
std::unordered_map< VertexType, ContourRef, VertexHash > VertexToContourMap
Definition: itkContourExtractor2DImageFilter.h:287
itk::ContourExtractor2DImageFilter::VertexHash
Definition: itkContourExtractor2DImageFilter.h:241
itkConceptMacro
#define itkConceptMacro(name, concept)
Definition: itkConceptChecking.h:64
itk::ContourExtractor2DImageFilter::VertexHash::operator()
SizeValueType operator()(const VertexType &k) const
Definition: itkContourExtractor2DImageFilter.h:245
itk::ContourExtractor2DImageFilter::VertexType
typename OutputPathType::VertexType VertexType
Definition: itkContourExtractor2DImageFilter.h:131
itk::ContourExtractor2DImageFilter::VertexHash::float_hash
SizeValueType float_hash(const CoordinateType &k) const
Definition: itkContourExtractor2DImageFilter.h:261
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkArray.h:26
itk::ContinuousIndex
A templated class holding a point in n-Dimensional image space.
Definition: itkContinuousIndex.h:46
itk::ContourExtractor2DImageFilter::InputRealType
typename NumericTraits< InputPixelType >::RealType InputRealType
Definition: itkContourExtractor2DImageFilter.h:135
itk::ContourExtractor2DImageFilter::m_VertexConnectHighPixels
bool m_VertexConnectHighPixels
Definition: itkContourExtractor2DImageFilter.h:208
itk::Concept::HasPixelTraits
Definition: itkConceptChecking.h:750
itk::ContourExtractor2DImageFilter::InputOffsetType
typename InputImageType::OffsetType InputOffsetType
Definition: itkContourExtractor2DImageFilter.h:128
itk::ContourExtractor2DImageFilter::InputImageType
TInputImage InputImageType
Definition: itkContourExtractor2DImageFilter.h:109
itk::ContourExtractor2DImageFilter::ContourType
Definition: itkContourExtractor2DImageFilter.h:228
itkPolyLineParametricPath.h
itk::VectorContainer
Define a front-end to the STL "vector" container that conforms to the IndexedContainerInterface.
Definition: itkVectorContainer.h:48
itk::ContourExtractor2DImageFilter::InputPixelType
typename InputImageType::PixelType InputPixelType
Definition: itkContourExtractor2DImageFilter.h:126
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:83