1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================*/
18 #ifndef __itkBinaryThinningImageFilter3D_h
\r
19 #define __itkBinaryThinningImageFilter3D_h
\r
21 #include <itkNeighborhoodIterator.h>
\r
22 #include <itkImageToImageFilter.h>
\r
23 #include <itkImageRegionIteratorWithIndex.h>
\r
24 #include <itkConstantBoundaryCondition.h>
\r
28 /** \class BinaryThinningImageFilter3D
\r
30 * \brief This filter computes one-pixel-wide skeleton of a 3D input image.
\r
32 * This class is parametrized over the type of the input image
\r
33 * and the type of the output image.
\r
35 * The input is assumed to be a binary image. All non-zero valued voxels
\r
36 * are set to 1 internally to simplify the computation. The filter will
\r
37 * produce a skeleton of the object. The output background values are 0,
\r
38 * and the foreground values are 1.
\r
40 * A 26-neighbourhood configuration is used for the foreground and a
\r
41 * 6-neighbourhood configuration for the background. Thinning is performed
\r
42 * symmetrically in order to guarantee that the skeleton lies medial within
\r
45 * This filter is a parallel thinning algorithm and is an implementation
\r
46 * of the algorithm described in:
\r
48 * T.C. Lee, R.L. Kashyap, and C.N. Chu.
\r
49 * Building skeleton models via 3-D medial surface/axis thinning algorithms.
\r
50 * Computer Vision, Graphics, and Image Processing, 56(6):462--478, 1994.
\r
52 * To do: Make use of multi-threading.
\r
54 * \author Hanno Homann, Oxford University, Wolfson Medical Vision Lab, UK.
\r
56 * \sa MorphologyImageFilter
\r
57 * \ingroup ImageEnhancement MathematicalMorphologyImageFilters
\r
60 template <class TInputImage,class TOutputImage>
\r
61 class BinaryThinningImageFilter3D :
\r
62 public ImageToImageFilter<TInputImage,TOutputImage>
\r
65 /** Standard class typedefs. */
\r
66 typedef BinaryThinningImageFilter3D Self;
\r
67 typedef ImageToImageFilter<TInputImage,TOutputImage> Superclass;
\r
68 typedef SmartPointer<Self> Pointer;
\r
69 typedef SmartPointer<const Self> ConstPointer;
\r
71 /** Method for creation through the object factory */
\r
74 /** Run-time type information (and related methods). */
\r
75 itkTypeMacro( BinaryThinningImageFilter3D, ImageToImageFilter );
\r
77 /** Type for input image. */
\r
78 typedef TInputImage InputImageType;
\r
80 /** Type for output image: Skelenton of the object. */
\r
81 typedef TOutputImage OutputImageType;
\r
83 /** Type for the region of the input image. */
\r
84 typedef typename InputImageType::RegionType RegionType;
\r
86 /** Type for the index of the input image. */
\r
87 typedef typename RegionType::IndexType IndexType;
\r
89 /** Type for the pixel type of the input image. */
\r
90 typedef typename InputImageType::PixelType InputImagePixelType ;
\r
92 /** Type for the pixel type of the input image. */
\r
93 typedef typename OutputImageType::PixelType OutputImagePixelType ;
\r
95 /** Type for the size of the input image. */
\r
96 typedef typename RegionType::SizeType SizeType;
\r
98 /** Pointer Type for input image. */
\r
99 typedef typename InputImageType::ConstPointer InputImagePointer;
\r
101 /** Pointer Type for the output image. */
\r
102 typedef typename OutputImageType::Pointer OutputImagePointer;
\r
104 /** Boundary condition type for the neighborhood iterator */
\r
105 typedef ConstantBoundaryCondition< TInputImage > ConstBoundaryConditionType;
\r
107 /** Neighborhood iterator type */
\r
108 typedef NeighborhoodIterator<TInputImage, ConstBoundaryConditionType> NeighborhoodIteratorType;
\r
110 /** Neighborhood type */
\r
111 typedef typename NeighborhoodIteratorType::NeighborhoodType NeighborhoodType;
\r
113 /** Get Skelenton by thinning image. */
\r
114 OutputImageType * GetThinning(void);
\r
116 /** ImageDimension enumeration */
\r
117 itkStaticConstMacro(InputImageDimension, unsigned int,
\r
118 TInputImage::ImageDimension );
\r
119 itkStaticConstMacro(OutputImageDimension, unsigned int,
\r
120 TOutputImage::ImageDimension );
\r
122 #ifdef ITK_USE_CONCEPT_CHECKING
\r
123 /** Begin concept checking */
\r
124 itkConceptMacro(SameDimensionCheck,
\r
125 (Concept::SameDimension<InputImageDimension, 3>));
\r
126 itkConceptMacro(SameTypeCheck,
\r
127 (Concept::SameType<InputImagePixelType, OutputImagePixelType>));
\r
128 itkConceptMacro(InputAdditiveOperatorsCheck,
\r
129 (Concept::AdditiveOperators<InputImagePixelType>));
\r
130 itkConceptMacro(InputConvertibleToIntCheck,
\r
131 (Concept::Convertible<InputImagePixelType, int>));
\r
132 itkConceptMacro(IntConvertibleToInputCheck,
\r
133 (Concept::Convertible<int, InputImagePixelType>));
\r
134 itkConceptMacro(InputIntComparableCheck,
\r
135 (Concept::Comparable<InputImagePixelType, int>));
\r
136 /** End concept checking */
\r
140 BinaryThinningImageFilter3D();
\r
141 virtual ~BinaryThinningImageFilter3D() {};
\r
142 void PrintSelf(std::ostream& os, Indent indent) const;
\r
144 /** Compute thinning Image. */
\r
145 void GenerateData();
\r
147 /** Prepare data. */
\r
148 void PrepareData();
\r
150 /** Compute thinning Image. */
\r
151 void ComputeThinImage();
\r
153 /** isEulerInvariant [Lee94] */
\r
154 bool isEulerInvariant(NeighborhoodType neighbors, int *LUT);
\r
155 void fillEulerLUT(int *LUT);
\r
156 /** isSimplePoint [Lee94] */
\r
157 bool isSimplePoint(NeighborhoodType neighbors);
\r
158 /** Octree_labeling [Lee94] */
\r
159 void Octree_labeling(int octant, int label, int *cube);
\r
163 BinaryThinningImageFilter3D(const Self&); //purposely not implemented
\r
164 void operator=(const Self&); //purposely not implemented
\r
166 }; // end of BinaryThinningImageFilter3D class
\r
168 } //end namespace itk
\r
170 #ifndef ITK_MANUAL_INSTANTIATION
\r
171 #include "itkBinaryThinningImageFilter3D.txx"
\r