ITK  4.6.0
Insight Segmentation and Registration Toolkit
itkContourExtractor2DImageFilter.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
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 "itksys/hash_map.hxx"
25 #include "vcl_deque.h"
26 #include "vcl_list.h"
27 
28 namespace itk
29 {
95 template< typename TInputImage >
97  public ImageToPathFilter< TInputImage, PolyLineParametricPath< 2 > >
98 {
99 public:
101  itkStaticConstMacro(InputImageDimension, unsigned int,
102  TInputImage::ImageDimension);
103 
105  typedef TInputImage InputImageType;
107 
113 
115  itkNewMacro(Self);
116 
119 
121  typedef typename InputImageType::Pointer InputImagePointer;
122  typedef typename InputImageType::PixelType InputPixelType;
123  typedef typename InputImageType::IndexType InputIndexType;
124  typedef typename InputImageType::OffsetType InputOffsetType;
125  typedef typename InputImageType::RegionType InputRegionType;
129 
132 
133  typedef typename VertexListType::ConstPointer
137  itkSetMacro(ReverseContourOrientation, bool);
138  itkGetConstReferenceMacro(ReverseContourOrientation, bool);
139  itkBooleanMacro(ReverseContourOrientation);
141 
145  itkSetMacro(VertexConnectHighPixels, bool);
146  itkGetConstReferenceMacro(VertexConnectHighPixels, bool);
147  itkBooleanMacro(VertexConnectHighPixels);
149 
152  void SetRequestedRegion(const InputRegionType region);
153 
154  itkGetConstReferenceMacro(RequestedRegion, InputRegionType);
155  void ClearRequestedRegion();
156 
159  itkSetMacro(ContourValue, InputRealType);
160  itkGetConstReferenceMacro(ContourValue, InputRealType);
162 
163 #ifdef ITK_USE_CONCEPT_CHECKING
164  // Begin concept checking
165  itkConceptMacro( DimensionShouldBe2,
166  ( Concept::SameDimension< itkGetStaticConstMacro(InputImageDimension), 2 > ) );
167  itkConceptMacro( InputPixelTypeComparable,
169  itkConceptMacro( InputHasPixelTraitsCheck,
171  itkConceptMacro( InputHasNumericTraitsCheck,
173  // End concept checking
174 #endif
175 
176 protected:
177 
180  void PrintSelf(std::ostream & os, Indent indent) const;
181 
182  void GenerateData();
183 
187  virtual void GenerateInputRequestedRegion();
188 
189 private:
191  InputPixelType toValue,
192  InputIndexType fromIndex,
193  InputOffsetType toOffset);
194 
195  void AddSegment(const VertexType from, const VertexType to);
196 
197  void FillOutputs();
198 
199  ContourExtractor2DImageFilter(const Self &); //purposely not implemented
200  void operator=(const Self &); //purposely not implemented
201 
208 
209  // Represent each contour as deque of vertices to facilitate addition of
210  // nodes at beginning or end. At the end of the processing, we will copy
211  // the contour into a PolyLineParametricPath.
212  // We subclass the deque to store an additional bit of information: an
213  // identification number for each growing contour. We use this number so
214  // that when it becomes necessary to merge two growing contours, we can
215  // merge the newer one into the older one. This helps because then we can
216  // guarantee that the output contour list is ordered from left to right,
217  // top to bottom (in terms of the first pixel of the contour encountered
218  // by the marching squares). Currently we make no guarantees that this
219  // pixel is the first pixel in the contour list, just that the contours
220  // are so ordered in the output. Ensuring this latter condition (first
221  // pixel traversed = first pixel in contour) would be possible by either
222  // changing the merging rules, which would make the contouring operation
223  //slower, or by storing additional data as to which pixel was first.
224  class ContourType:public vcl_deque< VertexType >
225  {
226 public:
227  unsigned int m_ContourNumber;
228  };
229 
230  // Store all the growing contours in a list. We may need to delete contours
231  // from anywhere in the sequence (when we merge them together), so we need to
232  // use a list instead of a vector or similar.
233  typedef vcl_list< ContourType > ContourContainer;
234  typedef typename ContourContainer::iterator ContourRef;
235 
236  // declare the hash function we are using for the hash_map.
237  struct VertexHash {
239  inline SizeValueType operator()(const VertexType & k) const
240  {
241  // Xor the hashes of the vertices together, after multiplying the
242  // first by some number, so that identical (x,y) vertex indices
243  // don't all hash to the same bucket. This is a decent if not
244  // optimal hash.
245  const SizeValueType hashVertex1 = this->float_hash(k[0] * 0xbeef);
246  const SizeValueType hashVertex2 = this->float_hash(k[1]);
247  const SizeValueType hashValue = hashVertex1 ^ hashVertex2;
248 
249  return hashValue;
250  }
251 
252  // Define hash function for floats. Based on method from
253  // http://www.brpreiss.com/books/opus4/html/page217.html
254  inline SizeValueType float_hash(const CoordinateType & k) const
255  {
256  if ( k == 0 )
257  {
258  return 0;
259  }
260  int exponent;
261  CoordinateType mantissa = vcl_frexp(k, &exponent);
262  SizeValueType value = static_cast< SizeValueType >( std::fabs(mantissa) );
263  value = ( 2 * value - 1 ) * ~0U;
264  return value;
265  }
266  };
267 
268  // We use a hash to associate the endpoints of each contour with the
269  // contour itself. This makes it easy to look up which contour we should add
270  // a new arc to.
271  // We can't store the contours themselves in the hashtable because we
272  // need to have two tables (one to hash from beginpoint -> contour and one
273  // for endpoint -> contour), and sometimes will remove a contour from the
274  // tables (if it has been closed or merged with another contour). So in the
275  // hash table we store a reference to the contour. Because sometimes we will
276  // need to merge contours, we need to be able to quickly remove contours
277  // from our list when they have been merged into another. Thus, we store
278  // an iterator pointing to the contour in the list.
279 
280  typedef itksys::hash_map< VertexType, ContourRef, VertexHash > VertexToContourMap;
281  typedef typename VertexToContourMap::iterator VertexMapIterator;
282  typedef typename VertexToContourMap::value_type VertexContourRefPair;
283 
284  // The contours we find in the image are stored here
286 
287  // And indexed by their beginning and ending points here
290 };
291 } // end namespace itk
292 
293 #ifndef ITK_MANUAL_INSTANTIATION
294 #include "itkContourExtractor2DImageFilter.hxx"
295 #endif
296 
297 #endif
void AddSegment(const VertexType from, const VertexType to)
Represent a path of line segments through ND Space.
Light weight base class for most itk classes.
void PrintSelf(std::ostream &os, Indent indent) const
VertexType InterpolateContourPosition(InputPixelType fromValue, InputPixelType toValue, InputIndexType fromIndex, InputOffsetType toOffset)
SizeValueType float_hash(const CoordinateType &k) const
virtual void GenerateInputRequestedRegion()
Base class for filters that take an image as input and produce an path as output. ...
ImageToPathFilter< InputImageType, OutputPathType > Superclass
unsigned long SizeValueType
Definition: itkIntTypes.h:143
NumericTraits< InputPixelType >::RealType InputRealType
SizeValueType operator()(const VertexType &k) const
A templated class holding a point in n-Dimensional image space.
VertexToContourMap::value_type VertexContourRefPair
Define a front-end to the STL &quot;vector&quot; container that conforms to the IndexedContainerInterface.
Control indentation during Print() invocation.
Definition: itkIndent.h:49
itksys::hash_map< VertexType, ContourRef, VertexHash > VertexToContourMap
void SetRequestedRegion(const InputRegionType region)
Define additional traits for native types such as int or float.
Computes a list of PolyLineParametricPath objects from the contours in a 2D image.
#define itkConceptMacro(name, concept)