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://oncora1.lyon.fnclcc.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 ======================================================================-====*/
19 #ifndef CLITKEXTRACTLUNGSFILTER_H
20 #define CLITKEXTRACTLUNGSFILTER_H
23 #include "clitkFilterBase.h"
24 #include "clitkDecomposeAndReconstructImageFilter.h"
25 #include "clitkExplosionControlledThresholdConnectedImageFilter.h"
26 #include "clitkSegmentationFunctions.h"
29 #include "itkStatisticsImageFilter.h"
33 //--------------------------------------------------------------------
35 Try to extract the Lung part of a thorax CT. Inspired by
36 Rikxoort2009, Section IIA, MedPhys.
38 - First, all air besides lungs and thrachea is removed, by
39 removing the second largest label of the firstLabelImage and
40 setting the remainder to 0HU . This modified input is optimally
41 thresholded (Otsu1979).
43 - Trachea and bronchi are grown from seeds in the top of the image
44 by explosion controlled region growing, slightly dilated and
45 removed from the second label image.
47 - Left and right lung are separated (if necessary) by erosion and
48 reconstructed by conditional dilation.
50 - TRACHEA is available at the end
52 TODO ********** Remaining holes can be filled afterwards (clitkFillMask).
55 //--------------------------------------------------------------------
57 template <class TInputImageType, class TMaskImageType>
58 class ITK_EXPORT ExtractLungFilter:
59 public clitk::FilterBase,
60 public itk::ImageToImageFilter<TInputImageType, TMaskImageType>
64 /** Standard class typedefs. */
65 typedef itk::ImageToImageFilter<TInputImageType, TMaskImageType> Superclass;
66 typedef ExtractLungFilter Self;
67 typedef itk::SmartPointer<Self> Pointer;
68 typedef itk::SmartPointer<const Self> ConstPointer;
70 /** Method for creation through the object factory. */
73 /** Run-time type information (and related methods). */
74 itkTypeMacro(ExtractLungFilter, ImageToImageFilter);
77 /** Some convenient typedefs */
78 typedef TInputImageType InputImageType;
79 typedef typename InputImageType::ConstPointer InputImageConstPointer;
80 typedef typename InputImageType::Pointer InputImagePointer;
81 typedef typename InputImageType::RegionType InputImageRegionType;
82 typedef typename InputImageType::PixelType InputImagePixelType;
83 typedef typename InputImageType::SizeType InputImageSizeType;
84 typedef typename InputImageType::IndexType InputImageIndexType;
86 typedef TMaskImageType MaskImageType;
87 typedef typename MaskImageType::ConstPointer MaskImageConstPointer;
88 typedef typename MaskImageType::Pointer MaskImagePointer;
89 typedef typename MaskImageType::RegionType MaskImageRegionType;
90 typedef typename MaskImageType::PixelType MaskImagePixelType;
91 typedef typename MaskImageType::SizeType MaskImageSizeType;
92 typedef typename MaskImageType::IndexType MaskImageIndexType;
94 itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension);
95 typedef int InternalPixelType;
96 typedef itk::Image<InternalPixelType, InputImageType::ImageDimension> InternalImageType;
97 typedef typename InternalImageType::Pointer InternalImagePointer;
98 typedef typename InternalImageType::IndexType InternalIndexType;
99 typedef LabelizeParameters<InternalPixelType> LabelParamType;
101 /** Connect inputs */
102 void SetInput(const InputImageType * image);
103 void SetInputPatientMask(MaskImageType * mask, MaskImagePixelType BG);
104 itkSetMacro(PatientMaskBackgroundValue, MaskImagePixelType);
105 itkGetConstMacro(PatientMaskBackgroundValue, MaskImagePixelType);
106 GGO_DefineOption(patientBG, SetPatientMaskBackgroundValue, MaskImagePixelType);
108 // Set all options at a time
109 template<class ArgsInfoType>
110 void SetArgsInfo(ArgsInfoType arg);
112 // Get output (only availabe after update !)
113 typename MaskImageType::Pointer GetTracheaImage() { return trachea; }
115 // Background / Foreground
116 itkGetConstMacro(BackgroundValue, MaskImagePixelType);
117 itkGetConstMacro(ForegroundValue, MaskImagePixelType);
119 // For common segmentation processes
120 itkSetMacro(MinimalComponentSize, int);
121 itkGetConstMacro(MinimalComponentSize, int);
122 GGO_DefineOption(minSize, SetMinimalComponentSize, int);
124 // Step 1 options RemoveAir
125 itkSetMacro(UpperThreshold, InputImagePixelType);
126 itkGetConstMacro(UpperThreshold, InputImagePixelType);
127 GGO_DefineOption(upper, SetUpperThreshold, InputImagePixelType);
129 itkSetMacro(LowerThreshold, InputImagePixelType);
130 itkGetConstMacro(LowerThreshold, InputImagePixelType);
131 itkSetMacro(UseLowerThreshold, bool);
132 itkGetConstMacro(UseLowerThreshold, bool);
133 itkBooleanMacro(UseLowerThreshold);
134 GGO_DefineOption_WithTest(lower, SetLowerThreshold, InputImagePixelType, UseLowerThreshold);
136 void SetLabelizeParameters1(LabelParamType * a) { m_LabelizeParameters1 = a; }
137 itkGetConstMacro(LabelizeParameters1, LabelParamType*);
138 GGO_DefineOption_LabelParam(1, SetLabelizeParameters1, LabelParamType);
140 // Step 2 options FindTrachea
141 itkSetMacro(UpperThresholdForTrachea, InputImagePixelType);
142 itkGetConstMacro(UpperThresholdForTrachea, InputImagePixelType);
143 GGO_DefineOption(upperThresholdForTrachea, SetUpperThresholdForTrachea, InputImagePixelType);
145 itkSetMacro(MultiplierForTrachea, double);
146 itkGetConstMacro(MultiplierForTrachea, double);
147 GGO_DefineOption(multiplierForTrachea, SetMultiplierForTrachea, double);
149 itkSetMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
150 itkGetConstMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
151 GGO_DefineOption(thresholdStepSizeForTrachea, SetThresholdStepSizeForTrachea, InputImagePixelType);
153 void AddSeed(InternalIndexType s);
154 std::vector<InternalIndexType> & GetSeeds() { return m_Seeds; }
155 GGO_DefineOption_Vector(seed, AddSeed, InternalIndexType, InputImageType::ImageDimension, true);
157 // Step 3 options ExtractLung
158 itkSetMacro(NumberOfHistogramBins, int);
159 itkGetConstMacro(NumberOfHistogramBins, int);
160 GGO_DefineOption(bins, SetNumberOfHistogramBins, int);
162 void SetLabelizeParameters2(LabelParamType* a) { m_LabelizeParameters2 = a; }
163 itkGetConstMacro(LabelizeParameters2, LabelParamType*);
164 GGO_DefineOption_LabelParam(2, SetLabelizeParameters2, LabelParamType);
166 // Step 4 options RemoveTrachea
167 itkSetMacro(RadiusForTrachea, int);
168 itkGetConstMacro(RadiusForTrachea, int);
169 GGO_DefineOption(radius, SetRadiusForTrachea, int);
171 void SetLabelizeParameters3(LabelParamType * a) { m_LabelizeParameters3 = a; }
172 itkGetConstMacro(LabelizeParameters3, LabelParamType*);
173 GGO_DefineOption_LabelParam(3, SetLabelizeParameters3, LabelParamType);
175 // Step 5 options LungSeparation
176 // itkSetMacro(FinalOpenClose, bool);
177 // itkGetConstMacro(FinalOpenClose, bool);
178 // itkBooleanMacro(FinalOpenClose);
180 // virtual void Update();
184 virtual ~ExtractLungFilter() {}
187 itkSetMacro(BackgroundValue, MaskImagePixelType);
188 itkSetMacro(ForegroundValue, MaskImagePixelType);
189 MaskImagePixelType m_PatientMaskBackgroundValue;
190 MaskImagePixelType m_BackgroundValue;
191 MaskImagePixelType m_ForegroundValue;
192 int m_MinimalComponentSize;
195 InputImagePixelType m_UpperThreshold;
196 InputImagePixelType m_LowerThreshold;
197 bool m_UseLowerThreshold;
198 LabelParamType* m_LabelizeParameters1;
201 InputImagePixelType m_UpperThresholdForTrachea;
202 InputImagePixelType m_ThresholdStepSizeForTrachea;
203 double m_MultiplierForTrachea;
204 std::vector<InternalIndexType> m_Seeds;
207 int m_NumberOfHistogramBins;
208 LabelParamType* m_LabelizeParameters2;
211 int m_RadiusForTrachea;
212 LabelParamType* m_LabelizeParameters3;
215 // bool m_FinalOpenClose;
217 virtual void GenerateOutputInformation();
218 virtual void GenerateData();
224 void RemoveTrachea();
225 void LungSeparation();
226 InputImageConstPointer input;
227 MaskImageConstPointer patient;
228 InputImagePointer working_input;
229 typename InternalImageType::Pointer working_image;
230 typename InternalImageType::Pointer trachea_tmp;
231 MaskImagePointer trachea;
234 ExtractLungFilter(const Self&); //purposely not implemented
235 void operator=(const Self&); //purposely not implemented
238 //--------------------------------------------------------------------
240 } // end namespace clitk
241 //--------------------------------------------------------------------
243 #ifndef ITK_MANUAL_INSTANTIATION
244 #include "clitkExtractLungFilter.txx"