NifTK  16.4.1 - 0798f20
CMIC's Translational Medical Imaging Platform
itkOrthogonalContourExtractor2DImageFilter.h
Go to the documentation of this file.
1 /*=============================================================================
2 
3  NifTK: A software platform for medical image computing.
4 
5  NOTE: This class has been modified from itkContourExtractor2DImageFilter.h/.txx
6  The original class would produce diagonal lines at corners. This class aims
7  to strictly produce contours that use vertical and horizontal lines only.
8 
9  For this reason, apart from this header, and a class name change, there is
10  as little code change as possible, so a simple diff should highlight the differences.
11 
12  The Copyright should therefore still belong to Insight Software Consortium.
13 ============================================================================*/
14 
15 /*=========================================================================
16 
17  Program: Insight Segmentation & Registration Toolkit
18  Module: itkContourExtractor2DImageFilter.h
19  Language: C++
20  Date: $Date$
21  Version: $Revision$
22 
23  Copyright (c) Insight Software Consortium. All rights reserved.
24  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
25 
26  This software is distributed WITHOUT ANY WARRANTY; without even
27  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
28  PURPOSE. See the above copyright notices for more information.
29 
30 =========================================================================*/
31 
32 #ifndef itkOrthogonalContourExtractor2DImageFilter_h
33 #define itkOrthogonalContourExtractor2DImageFilter_h
34 
35 #include <itkImageToPathFilter.h>
36 #include <itkNumericTraits.h>
37 #include <itkPolyLineParametricPath.h>
38 #include <itkConceptChecking.h>
39 #include <itksys/hash_map.hxx>
40 #include <vcl_deque.h>
41 #include <vcl_list.h>
42 
43 namespace itk
44 {
105 template <class TInputImage>
107  public ImageToPathFilter< TInputImage, PolyLineParametricPath<2> >
108 {
109 public:
111  itkStaticConstMacro(InputImageDimension, unsigned int,
112  TInputImage::ImageDimension);
113 
115  typedef TInputImage InputImageType;
116  typedef PolyLineParametricPath<2> OutputPathType;
117 
120  typedef ImageToPathFilter<InputImageType, OutputPathType> Superclass;
121  typedef SmartPointer<Self> Pointer;
122  typedef SmartPointer<const Self> ConstPointer;
123 
125  itkNewMacro(Self);
126 
128  itkTypeMacro(OrthogonalContourExtractor2DImageFilter, ImageToPathFilter);
129 
131  typedef typename InputImageType::Pointer InputImagePointer;
134  typedef typename InputImageType::OffsetType InputOffsetType;
136  typedef typename OutputPathType::Pointer OutputPathPointer;
137  typedef typename OutputPathType::VertexType VertexType;
138  typedef typename OutputPathType::VertexListType VertexListType;
139 
141  typedef typename NumericTraits<InputPixelType>::RealType InputRealType;
142 
143  typedef typename VertexListType::ConstPointer
147  itkSetMacro(ReverseContourOrientation, bool);
148  itkGetConstReferenceMacro(ReverseContourOrientation, bool);
149  itkBooleanMacro(ReverseContourOrientation);
150 
154  itkSetMacro(VertexConnectHighPixels, bool);
155  itkGetConstReferenceMacro(VertexConnectHighPixels, bool);
156  itkBooleanMacro(VertexConnectHighPixels);
157 
160  void SetRequestedRegion(const InputRegionType region);
161  itkGetConstReferenceMacro(RequestedRegion, InputRegionType);
162  void ClearRequestedRegion();
163 
166  itkSetMacro(ContourValue,InputRealType);
167  itkGetConstReferenceMacro(ContourValue, InputRealType);
168 
169 
170 #ifdef ITK_USE_CONCEPT_CHECKING
171 
172  itkConceptMacro(DimensionShouldBe2,
173  (Concept::SameDimension<itkGetStaticConstMacro(InputImageDimension),2>));
174  itkConceptMacro(InputPixelTypeComparable,
175  (Concept::Comparable<InputPixelType>));
176  itkConceptMacro(InputHasPixelTraitsCheck,
177  (Concept::HasPixelTraits<InputPixelType>));
178  itkConceptMacro(InputHasNumericTraitsCheck,
179  (Concept::HasNumericTraits<InputPixelType>));
181 #endif
182 
183 protected:
184 
187  void PrintSelf(std::ostream& os, Indent indent) const;
188 
189  void GenerateData();
190 
194  virtual void GenerateInputRequestedRegion()
195  throw(InvalidRequestedRegionError);
196 
197 private:
198  VertexType InterpolateContourPosition(InputPixelType fromValue,
199  InputPixelType toValue,
200  InputIndexType fromIndex,
201  InputOffsetType toOffset);
202  void AddSegment(const VertexType from, const VertexType to);
203  void FillOutputs();
204  OrthogonalContourExtractor2DImageFilter(const Self&); //purposely not implemented
205  void operator=(const Self&); //purposely not implemented
206 
207  InputRealType m_ContourValue;
208  bool m_ReverseContourOrientation;
209  bool m_VertexConnectHighPixels;
210  bool m_UseCustomRegion;
211  InputRegionType m_RequestedRegion;
212  unsigned int m_NumberOfContoursCreated;
213 
214  // Represent each contour as deque of vertices to facilitate addition of
215  // nodes at beginning or end. At the end of the processing, we will copy
216  // the contour into a PolyLineParametricPath.
217  // We subclass the deque to store an additional bit of information: an
218  // identification number for each growing contour. We use this number so
219  // that when it becomes necessary to merge two growing contours, we can
220  // merge the newer one into the older one. This helps because then we can
221  // guarantee that the output contour list is ordered from left to right,
222  // top to bottom (in terms of the first pixel of the contour encountered
223  // by the marching squares). Currently we make no guarantees that this
224  // pixel is the first pixel in the contour list, just that the contours
225  // are so ordered in the output. Ensuring this latter condition (first
226  // pixel traversed = first pixel in contour) would be possible by either
227  // changing the merging rules, which would make the contouring operation
228  //slower, or by storing additional data as to which pixel was first.
229  class ContourType : public vcl_deque<VertexType>
230  {
231  public:
232  unsigned int m_ContourNumber;
233  };
234 
235  // Store all the growing contours in a list. We may need to delete contours
236  // from anywhere in the sequence (when we merge them together), so we need to
237  // use a list instead of a vector or similar.
238  typedef vcl_list<ContourType> ContourContainer;
239  typedef typename ContourContainer::iterator ContourRef;
240 
241  // declare the hash function we are using for the hash_map.
242  struct VertexHash
243  {
244  typedef typename VertexType::CoordRepType CoordinateType;
245  inline size_t 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 size_t hashVertex1 = this->float_hash(k[0] * 0xbeef);
252  const size_t hashVertex2 = this->float_hash(k[1]);
253  const size_t hashValue = hashVertex1 ^ hashVertex2;
254  return hashValue;
255  }
256 
257  // Define hash function for floats. Based on method from
258  // http://www.brpreiss.com/books/opus4/html/page217.html
259  inline size_t float_hash(const CoordinateType &k) const
260  {
261  if (k == 0)
262  {
263  return 0;
264  }
265  int exponent;
266  CoordinateType mantissa = vcl_frexp(k, &exponent);
267  size_t value = static_cast<size_t>(vcl_fabs(mantissa));
268  value = ( 2 * value - 1 ) * ~0U;
269  return value;
270  }
271  };
272 
273  // We use a hash to associate the endpoints of each contour with the
274  // contour itself. This makes it easy to look up which contour we should add
275  // a new arc to.
276  // We can't store the contours themselves in the hashtable because we
277  // need to have two tables (one to hash from beginpoint -> contour and one
278  // for endpoint -> contour), and sometimes will remove a contour from the
279  // tables (if it has been closed or merged with another contour). So in the
280  // hash table we store a reference to the contour. Because sometimes we will
281  // need to merge contours, we need to be able to quickly remove contours
282  // from our list when they have been merged into another. Thus, we store
283  // an iterator pointing to the contour in the list.
284 
285  typedef itksys::hash_map<VertexType, ContourRef, VertexHash> VertexToContourMap;
286  typedef typename VertexToContourMap::iterator VertexMapIterator;
287  typedef typename VertexToContourMap::value_type VertexContourRefPair;
288 
289  // The contours we find in the image are stored here
290  ContourContainer m_Contours;
291 
292  // And indexed by their beginning and ending points here
293  VertexToContourMap m_ContourStarts;
294  VertexToContourMap m_ContourEnds;
295 
296 };
297 
298 } // end namespace itk
299 
300 #ifndef ITK_MANUAL_INSTANTIATION
301 #include "itkOrthogonalContourExtractor2DImageFilter.txx"
302 #endif
303 
304 #endif
OutputPathType::VertexListType VertexListType
Definition: itkOrthogonalContourExtractor2DImageFilter.h:138
OutputPathType::VertexType VertexType
Definition: itkOrthogonalContourExtractor2DImageFilter.h:137
OutputPathType::Pointer OutputPathPointer
Definition: itkOrthogonalContourExtractor2DImageFilter.h:136
PolyLineParametricPath< 2 > OutputPathType
Definition: itkOrthogonalContourExtractor2DImageFilter.h:116
Definition: niftkITKAffineResampleImage.cxx:74
ImageType::IndexType IndexType
Definition: niftkMakeLapUSProbeBasicModel.cxx:32
InputImageType::PixelType InputPixelType
Definition: itkOrthogonalContourExtractor2DImageFilter.h:132
TInputImage InputImageType
Definition: itkOrthogonalContourExtractor2DImageFilter.h:115
InputImageType::Pointer InputImagePointer
Definition: itkOrthogonalContourExtractor2DImageFilter.h:128
Computes a list of PolyLineParametricPath objects from the contours in a 2D image.
Definition: itkOrthogonalContourExtractor2DImageFilter.h:106
GLsizei const GLfloat * value
Definition: glew.h:1833
InputImageType::OffsetType InputOffsetType
Definition: itkOrthogonalContourExtractor2DImageFilter.h:134
VertexListType::ConstPointer VertexListConstPointer
Definition: itkOrthogonalContourExtractor2DImageFilter.h:144
float PixelType
Definition: niftkBreastDCEandADC.cxx:88
SmartPointer< Self > Pointer
Definition: itkOrthogonalContourExtractor2DImageFilter.h:121
ImageType::RegionType RegionType
Definition: niftkMakeLapUSProbeBasicModel.cxx:30
NumericTraits< InputPixelType >::RealType InputRealType
Definition: itkOrthogonalContourExtractor2DImageFilter.h:141
SmartPointer< const Self > ConstPointer
Definition: itkOrthogonalContourExtractor2DImageFilter.h:122
OrthogonalContourExtractor2DImageFilter Self
Definition: itkOrthogonalContourExtractor2DImageFilter.h:119
ImageToPathFilter< InputImageType, OutputPathType > Superclass
Definition: itkOrthogonalContourExtractor2DImageFilter.h:120
InputImageType::RegionType InputRegionType
Definition: itkOrthogonalContourExtractor2DImageFilter.h:135
InputImageType::IndexType InputIndexType
Definition: itkOrthogonalContourExtractor2DImageFilter.h:133