]> Creatis software - clitk.git/blob - segmentation/clitkExtractLungFilter.h
clitkExtractLung - new option
[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://www.centreleonberard.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 uchar InternalPixelType;
102     typedef itk::Image<InternalPixelType, ImageType::ImageDimension> InternalImageType;
103     typedef typename InternalImageType::Pointer                      InternalImagePointer;
104     typedef typename InternalImageType::IndexType                    InternalIndexType;
105     typedef LabelizeParameters<InternalPixelType>                    LabelParamType;
106     
107     /** Connect inputs */
108     void SetInput(const ImageType * image);
109     itkSetMacro(PatientMaskBackgroundValue, MaskImagePixelType);
110     itkGetConstMacro(PatientMaskBackgroundValue, MaskImagePixelType);
111
112     // Output filename  (for AFBD)
113     itkSetMacro(OutputLungFilename, std::string);
114     itkGetMacro(OutputLungFilename, std::string);
115
116     itkSetMacro(OutputTracheaFilename, std::string);
117     itkGetMacro(OutputTracheaFilename, std::string);
118
119     // Get output (only availabe after update !)
120     typename MaskImageType::Pointer GetTracheaImage() { return trachea; }
121
122     // Background / Foreground
123     itkGetConstMacro(BackgroundValue, MaskImagePixelType);
124     itkGetConstMacro(ForegroundValue, MaskImagePixelType);
125
126     // For common segmentation processes
127     itkSetMacro(MinimalComponentSize, int);
128     itkGetConstMacro(MinimalComponentSize, int);
129
130     // Step 1 options RemoveAir
131     itkSetMacro(UpperThreshold, InputImagePixelType);
132     itkGetConstMacro(UpperThreshold, InputImagePixelType);
133
134     itkSetMacro(NumberOfSlicesToSkipBeforeSearchingSeed, int);
135     itkGetConstMacro(NumberOfSlicesToSkipBeforeSearchingSeed, int);
136     
137     itkSetMacro(LowerThreshold, InputImagePixelType);
138     itkGetConstMacro(LowerThreshold, InputImagePixelType);
139     itkSetMacro(UseLowerThreshold, bool);
140     itkGetConstMacro(UseLowerThreshold, bool);
141     itkBooleanMacro(UseLowerThreshold);
142
143     void SetLabelizeParameters1(LabelParamType * a) { m_LabelizeParameters1 = a; }
144     itkGetConstMacro(LabelizeParameters1, LabelParamType*);
145
146     // Step 2 options FindTrachea
147     itkSetMacro(UpperThresholdForTrachea, InputImagePixelType);
148     itkGetConstMacro(UpperThresholdForTrachea, InputImagePixelType);
149
150     itkSetMacro(MultiplierForTrachea, double);
151     itkGetConstMacro(MultiplierForTrachea, double);
152
153     itkSetMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
154     itkGetConstMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
155
156     void AddSeed(InternalIndexType s);
157     std::vector<InternalIndexType> & GetSeeds() { return  m_Seeds; }
158
159     itkSetMacro(TracheaVolumeMustBeCheckedFlag, bool);
160     itkGetConstMacro(TracheaVolumeMustBeCheckedFlag, bool);
161     itkBooleanMacro(TracheaVolumeMustBeCheckedFlag);    
162
163     itkSetMacro(VerboseRegionGrowingFlag, bool);
164     itkGetConstMacro(VerboseRegionGrowingFlag, bool);
165     itkBooleanMacro(VerboseRegionGrowingFlag);    
166
167     // Step 3 options ExtractLung
168     itkSetMacro(NumberOfHistogramBins, int);
169     itkGetConstMacro(NumberOfHistogramBins, int);
170
171     void SetLabelizeParameters2(LabelParamType* a) { m_LabelizeParameters2 = a; }
172     itkGetConstMacro(LabelizeParameters2, LabelParamType*);
173
174     // Step 4 options RemoveTrachea
175     itkSetMacro(RadiusForTrachea, int);
176     itkGetConstMacro(RadiusForTrachea, int);
177     
178     void SetLabelizeParameters3(LabelParamType * a) { m_LabelizeParameters3 = a; }
179     itkGetConstMacro(LabelizeParameters3, LabelParamType*);
180
181     // Step 5 final openclose
182     itkSetMacro(OpenCloseFlag, bool);
183     itkGetConstMacro(OpenCloseFlag, bool);
184     itkBooleanMacro(OpenCloseFlag);
185
186     itkSetMacro(OpenCloseRadius, int);
187     itkGetConstMacro(OpenCloseRadius, int);
188     
189     // Step 6 fill holes
190     itkSetMacro(FillHolesFlag, bool);
191     itkGetConstMacro(FillHolesFlag, bool);
192     itkBooleanMacro(FillHolesFlag);
193
194     // Separate lungs
195     itkSetMacro(SeparateLungsFlag, bool);
196     itkGetConstMacro(SeparateLungsFlag, bool);
197     itkBooleanMacro(SeparateLungsFlag);
198
199     // Step Auto Crop
200     itkSetMacro(AutoCrop, bool);
201     itkGetConstMacro(AutoCrop, bool);
202     itkBooleanMacro(AutoCrop);
203
204   protected:
205     ExtractLungFilter();
206     virtual ~ExtractLungFilter() {}
207
208     // Main members
209     InputImageConstPointer input;
210     MaskImagePointer patient;
211     InputImagePointer working_input;
212     std::string m_OutputLungFilename;
213     std::string m_OutputTracheaFilename;
214     MaskImagePointer working_mask;  
215     MaskImagePointer trachea;
216     unsigned int m_MaxSeedNumber;
217
218     // Global options
219     itkSetMacro(BackgroundValue, MaskImagePixelType);
220     itkSetMacro(ForegroundValue, MaskImagePixelType);
221     MaskImagePixelType m_PatientMaskBackgroundValue;
222     MaskImagePixelType m_BackgroundValue;
223     MaskImagePixelType m_ForegroundValue;
224     int m_MinimalComponentSize;
225     bool m_AutoCrop;
226
227     // Step 1
228     InputImagePixelType m_UpperThreshold;
229     InputImagePixelType m_LowerThreshold;
230     bool m_UseLowerThreshold;
231     LabelParamType* m_LabelizeParameters1;
232
233     // Step 2
234     InputImagePixelType m_UpperThresholdForTrachea;
235     InputImagePixelType m_ThresholdStepSizeForTrachea;
236     double m_MultiplierForTrachea;
237     std::vector<InternalIndexType> m_Seeds;
238     int m_NumberOfSlicesToSkipBeforeSearchingSeed;
239     bool m_TracheaVolumeMustBeCheckedFlag;
240     bool m_VerboseRegionGrowingFlag;
241
242     // Step 3
243     int m_NumberOfHistogramBins;
244     LabelParamType* m_LabelizeParameters2;
245
246     // Step 4
247     int m_RadiusForTrachea;
248     LabelParamType* m_LabelizeParameters3;
249
250     // Step 5
251     bool m_OpenCloseFlag;    
252     int m_OpenCloseRadius;
253
254     // Step 6
255     bool m_FillHolesFlag;    
256     InputImageSizeType m_FillHolesDirections;
257
258     bool m_SeparateLungsFlag;
259     
260     // Main functions
261     virtual void GenerateOutputInformation();
262     virtual void GenerateInputRequestedRegion();
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