]> Creatis software - clitk.git/blob - segmentation/clitkExtractLungFilter.h
small improvement
[clitk.git] / segmentation / clitkExtractLungFilter.h
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to: 
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
8
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.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ======================================================================-====*/
18
19 #ifndef CLITKEXTRACTLUNGSFILTER_H
20 #define CLITKEXTRACTLUNGSFILTER_H
21
22 // clitk 
23 #include "clitkFilterBase.h"
24 #include "clitkDecomposeAndReconstructImageFilter.h"
25 #include "clitkExplosionControlledThresholdConnectedImageFilter.h"
26 #include "clitkSegmentationUtils.h"
27 #include "clitkFilterWithAnatomicalFeatureDatabaseManagement.h"
28
29 // itk
30 #include "itkStatisticsImageFilter.h"
31
32 namespace clitk {
33   
34   //--------------------------------------------------------------------
35   /*
36     Try to extract the Lung part of a thorax CT. Inspired by
37     Rikxoort2009, Section IIA, MedPhys.
38
39     - First, all air besides lungs and thrachea is removed, by
40     removing the second largest label of the firstLabelImage and
41     setting the remainder to 0HU . This modified input is optimally
42     thresholded (Otsu1979).
43
44     - Trachea and bronchi are grown from seeds in the top of the image
45     by explosion controlled region growing, slightly dilated and
46     removed from the second label image.
47
48     - Left and right lung are separated (if necessary) by erosion and
49     reconstructed by conditional dilation. 
50
51     - TRACHEA is available at the end
52
53     TODO ********** Remaining holes can be       filled afterwards (clitkFillMask).
54
55   */
56   //--------------------------------------------------------------------
57   
58   //--------------------------------------------------------------------
59   template <class TImageType>
60   class ITK_EXPORT ExtractLungFilter: 
61     public virtual clitk::FilterBase, 
62     public clitk::FilterWithAnatomicalFeatureDatabaseManagement,
63     public itk::ImageToImageFilter<TImageType, itk::Image<uchar, TImageType::ImageDimension> > 
64   {
65     
66   public:
67     /** Standard class typedefs. */
68     typedef itk::Image<uchar, TImageType::ImageDimension> MaskImageType;
69     typedef itk::ImageToImageFilter<TImageType, MaskImageType> Superclass;
70     typedef ExtractLungFilter              Self;
71     typedef itk::SmartPointer<Self>        Pointer;
72     typedef itk::SmartPointer<const Self>  ConstPointer;
73     
74     /** Method for creation through the object factory. */
75     itkNewMacro(Self);  
76     
77     /** Run-time type information (and related methods). */
78     itkTypeMacro(ExtractLungFilter, ImageToImageFilter);
79     FILTERBASE_INIT;
80
81     /** Some convenient typedefs */
82     typedef TImageType                       ImageType;
83     typedef typename ImageType::ConstPointer InputImageConstPointer;
84     typedef typename ImageType::Pointer      InputImagePointer;
85     typedef typename ImageType::RegionType   InputImageRegionType; 
86     typedef typename ImageType::PixelType    InputImagePixelType; 
87     typedef typename ImageType::SizeType     InputImageSizeType; 
88     typedef typename ImageType::IndexType    InputImageIndexType; 
89     typedef typename ImageType::PointType    InputImagePointType; 
90         
91     typedef typename MaskImageType::ConstPointer MaskImageConstPointer;
92     typedef typename MaskImageType::Pointer      MaskImagePointer;
93     typedef typename MaskImageType::RegionType   MaskImageRegionType; 
94     typedef typename MaskImageType::PixelType    MaskImagePixelType; 
95     typedef typename MaskImageType::SizeType     MaskImageSizeType; 
96     typedef typename MaskImageType::IndexType    MaskImageIndexType; 
97     typedef typename MaskImageType::PointType    MaskImagePointType; 
98
99     itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
100     typedef int InternalPixelType;
101     typedef itk::Image<InternalPixelType, ImageType::ImageDimension> InternalImageType;
102     typedef typename InternalImageType::Pointer                      InternalImagePointer;
103     typedef typename InternalImageType::IndexType                    InternalIndexType;
104     typedef LabelizeParameters<InternalPixelType>                    LabelParamType;
105     
106     /** Connect inputs */
107     void SetInput(const ImageType * image);
108     itkSetMacro(PatientMaskBackgroundValue, MaskImagePixelType);
109     itkGetConstMacro(PatientMaskBackgroundValue, MaskImagePixelType);
110     GGO_DefineOption(patientBG, SetPatientMaskBackgroundValue, MaskImagePixelType);
111
112     // Output filename  (for AFBD)
113     itkSetMacro(OutputLungFilename, std::string);
114     itkGetMacro(OutputLungFilename, std::string);
115     GGO_DefineOption(output, SetOutputLungFilename, std::string);
116
117     itkSetMacro(OutputTracheaFilename, std::string);
118     itkGetMacro(OutputTracheaFilename, std::string);
119     GGO_DefineOption(outputTrachea, SetOutputTracheaFilename, std::string);
120
121     // Set all options at a time
122     template<class ArgsInfoType>
123       void SetArgsInfo(ArgsInfoType arg);
124
125     // Get output (only availabe after update !)
126     typename MaskImageType::Pointer GetTracheaImage() { return trachea; }
127
128     // Background / Foreground
129     itkGetConstMacro(BackgroundValue, MaskImagePixelType);
130     itkGetConstMacro(ForegroundValue, MaskImagePixelType);
131
132     // For common segmentation processes
133     itkSetMacro(MinimalComponentSize, int);
134     itkGetConstMacro(MinimalComponentSize, int);
135     GGO_DefineOption(minSize, SetMinimalComponentSize, int);
136
137     // Step 1 options RemoveAir
138     itkSetMacro(UpperThreshold, InputImagePixelType);
139     itkGetConstMacro(UpperThreshold, InputImagePixelType);
140     GGO_DefineOption(upper, SetUpperThreshold, InputImagePixelType);
141
142     itkSetMacro(NumberOfSlicesToSkipBeforeSearchingSeed, int);
143     itkGetConstMacro(NumberOfSlicesToSkipBeforeSearchingSeed, int);
144     GGO_DefineOption(skipslices, SetNumberOfSlicesToSkipBeforeSearchingSeed, int);
145     
146     itkSetMacro(LowerThreshold, InputImagePixelType);
147     itkGetConstMacro(LowerThreshold, InputImagePixelType);
148     itkSetMacro(UseLowerThreshold, bool);
149     itkGetConstMacro(UseLowerThreshold, bool);
150     itkBooleanMacro(UseLowerThreshold);
151     GGO_DefineOption_WithTest(lower, SetLowerThreshold, InputImagePixelType, UseLowerThreshold);
152
153     void SetLabelizeParameters1(LabelParamType * a) { m_LabelizeParameters1 = a; }
154     itkGetConstMacro(LabelizeParameters1, LabelParamType*);
155     GGO_DefineOption_LabelParam(1, SetLabelizeParameters1, LabelParamType);
156
157     // Step 2 options FindTrachea
158     itkSetMacro(UpperThresholdForTrachea, InputImagePixelType);
159     itkGetConstMacro(UpperThresholdForTrachea, InputImagePixelType);
160     GGO_DefineOption(upperThresholdForTrachea, SetUpperThresholdForTrachea, InputImagePixelType);
161
162     itkSetMacro(MultiplierForTrachea, double);
163     itkGetConstMacro(MultiplierForTrachea, double);
164     GGO_DefineOption(multiplierForTrachea, SetMultiplierForTrachea, double);
165
166     itkSetMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
167     itkGetConstMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
168     GGO_DefineOption(thresholdStepSizeForTrachea, SetThresholdStepSizeForTrachea, InputImagePixelType);
169
170     void AddSeed(InternalIndexType s);
171     std::vector<InternalIndexType> & GetSeeds() { return  m_Seeds; }
172     GGO_DefineOption_Vector(seed, AddSeed, InternalIndexType, ImageType::ImageDimension, true);
173
174     // Step 3 options ExtractLung
175     itkSetMacro(NumberOfHistogramBins, int);
176     itkGetConstMacro(NumberOfHistogramBins, int);
177     GGO_DefineOption(bins, SetNumberOfHistogramBins, int);
178
179     void SetLabelizeParameters2(LabelParamType* a) { m_LabelizeParameters2 = a; }
180     itkGetConstMacro(LabelizeParameters2, LabelParamType*);
181     GGO_DefineOption_LabelParam(2, SetLabelizeParameters2, LabelParamType);
182
183     // Step 4 options RemoveTrachea
184     itkSetMacro(RadiusForTrachea, int);
185     itkGetConstMacro(RadiusForTrachea, int);
186     GGO_DefineOption(radius, SetRadiusForTrachea, int);
187     
188     void SetLabelizeParameters3(LabelParamType * a) { m_LabelizeParameters3 = a; }
189     itkGetConstMacro(LabelizeParameters3, LabelParamType*);
190     GGO_DefineOption_LabelParam(3, SetLabelizeParameters3, LabelParamType);
191
192     // Step 5 final openclose
193     itkSetMacro(OpenClose, bool);
194     itkGetConstMacro(OpenClose, bool);
195     itkBooleanMacro(OpenClose);
196     GGO_DefineOption_Flag(openclose, SetOpenClose);
197
198     itkSetMacro(OpenCloseRadius, int);
199     itkGetConstMacro(OpenCloseRadius, int);
200     GGO_DefineOption(opencloseRadius, SetOpenCloseRadius, int);
201     
202     // Step 6 fill holes
203     itkSetMacro(FillHoles, bool);
204     itkGetConstMacro(FillHoles, bool);
205     itkBooleanMacro(FillHoles);
206     GGO_DefineOption_Flag(doNotFillHoles, SetFillHoles);
207
208   protected:
209     ExtractLungFilter();
210     virtual ~ExtractLungFilter() {}
211
212     // Main members
213     InputImageConstPointer input;
214     MaskImageConstPointer patient;
215     InputImagePointer working_input;
216     std::string m_OutputLungFilename;
217     std::string m_OutputTracheaFilename;
218     typename InternalImageType::Pointer working_image;  
219     typename InternalImageType::Pointer trachea_tmp;
220     MaskImagePointer trachea;
221     MaskImagePointer output;
222     unsigned int m_MaxSeedNumber;
223
224     // Global options
225     itkSetMacro(BackgroundValue, MaskImagePixelType);
226     itkSetMacro(ForegroundValue, MaskImagePixelType);
227     MaskImagePixelType m_PatientMaskBackgroundValue;
228     MaskImagePixelType m_BackgroundValue;
229     MaskImagePixelType m_ForegroundValue;
230     int m_MinimalComponentSize;
231
232     // Step 1
233     InputImagePixelType m_UpperThreshold;
234     InputImagePixelType m_LowerThreshold;
235     bool m_UseLowerThreshold;
236     LabelParamType* m_LabelizeParameters1;
237
238     // Step 2
239     InputImagePixelType m_UpperThresholdForTrachea;
240     InputImagePixelType m_ThresholdStepSizeForTrachea;
241     double m_MultiplierForTrachea;
242     std::vector<InternalIndexType> m_Seeds;
243     int m_NumberOfSlicesToSkipBeforeSearchingSeed;
244
245     // Step 3
246     int m_NumberOfHistogramBins;
247     LabelParamType* m_LabelizeParameters2;
248
249     // Step 4
250     int m_RadiusForTrachea;
251     LabelParamType* m_LabelizeParameters3;
252
253     // Step 5
254     bool m_OpenClose;    
255     int m_OpenCloseRadius;
256
257     // Step 6
258     bool m_FillHoles;    
259     InputImageSizeType m_FillHolesDirections;
260
261     // Main functions
262     virtual void GenerateOutputInformation();
263     virtual void GenerateData();
264     
265     // Functions for trachea extraction
266     bool SearchForTracheaSeed(int skip);
267     void SearchForTrachea();
268     void TracheaRegionGrowing();
269     double ComputeTracheaVolume();
270
271   private:
272     ExtractLungFilter(const Self&); //purposely not implemented
273     void operator=(const Self&); //purposely not implemented
274     
275   }; // end class
276   //--------------------------------------------------------------------
277
278 } // end namespace clitk
279 //--------------------------------------------------------------------
280
281 #ifndef ITK_MANUAL_INSTANTIATION
282 #include "clitkExtractLungFilter.txx"
283 #endif
284
285 #endif