]> Creatis software - clitk.git/blob - segmentation/clitkExtractLungFilter.h
separate airway tracking from extract lung
[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
28 // itk
29 #include "itkStatisticsImageFilter.h"
30
31 namespace clitk {
32   
33   //--------------------------------------------------------------------
34   /*
35     Try to extract the Lung part of a thorax CT. Inspired by
36     Rikxoort2009, Section IIA, MedPhys.
37
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).
42
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.
46
47     - Left and right lung are separated (if necessary) by erosion and
48     reconstructed by conditional dilation. 
49
50     - TRACHEA is available at the end
51
52     TODO ********** Remaining holes can be       filled afterwards (clitkFillMask).
53
54   */
55   //--------------------------------------------------------------------
56   
57   //--------------------------------------------------------------------
58   template <class TImageType, class TMaskImageType>
59   class ITK_EXPORT ExtractLungFilter: 
60     public virtual clitk::FilterBase, 
61     public itk::ImageToImageFilter<TImageType, TMaskImageType> 
62   {
63     
64   public:
65     /** Standard class typedefs. */
66     typedef itk::ImageToImageFilter<TImageType, TMaskImageType> Superclass;
67     typedef ExtractLungFilter              Self;
68     typedef itk::SmartPointer<Self>        Pointer;
69     typedef itk::SmartPointer<const Self>  ConstPointer;
70     
71     /** Method for creation through the object factory. */
72     itkNewMacro(Self);  
73     
74     /** Run-time type information (and related methods). */
75     itkTypeMacro(ExtractLungFilter, ImageToImageFilter);
76     FILTERBASE_INIT;
77
78     /** Some convenient typedefs */
79     typedef TImageType                       ImageType;
80     typedef typename ImageType::ConstPointer InputImageConstPointer;
81     typedef typename ImageType::Pointer      InputImagePointer;
82     typedef typename ImageType::RegionType   InputImageRegionType; 
83     typedef typename ImageType::PixelType    InputImagePixelType; 
84     typedef typename ImageType::SizeType     InputImageSizeType; 
85     typedef typename ImageType::IndexType    InputImageIndexType; 
86     typedef typename ImageType::PointType    InputImagePointType; 
87         
88     typedef TMaskImageType                       MaskImageType;
89     typedef typename MaskImageType::ConstPointer MaskImageConstPointer;
90     typedef typename MaskImageType::Pointer      MaskImagePointer;
91     typedef typename MaskImageType::RegionType   MaskImageRegionType; 
92     typedef typename MaskImageType::PixelType    MaskImagePixelType; 
93     typedef typename MaskImageType::SizeType     MaskImageSizeType; 
94     typedef typename MaskImageType::IndexType    MaskImageIndexType; 
95     typedef typename MaskImageType::PointType    MaskImagePointType; 
96
97     itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
98     typedef int InternalPixelType;
99     typedef itk::Image<InternalPixelType, ImageType::ImageDimension> InternalImageType;
100     typedef typename InternalImageType::Pointer                      InternalImagePointer;
101     typedef typename InternalImageType::IndexType                    InternalIndexType;
102     typedef LabelizeParameters<InternalPixelType>                    LabelParamType;
103     
104     /** Connect inputs */
105     void SetInput(const ImageType * image);
106     void SetInputPatientMask(MaskImageType * mask, MaskImagePixelType BG);
107     itkSetMacro(PatientMaskBackgroundValue, MaskImagePixelType);
108     itkGetConstMacro(PatientMaskBackgroundValue, MaskImagePixelType);
109     GGO_DefineOption(patientBG, SetPatientMaskBackgroundValue, MaskImagePixelType);
110
111     // Set all options at a time
112     template<class ArgsInfoType>
113       void SetArgsInfo(ArgsInfoType arg);
114
115     // Get output (only availabe after update !)
116     typename MaskImageType::Pointer GetTracheaImage() { return trachea; }
117
118     // Background / Foreground
119     itkGetConstMacro(BackgroundValue, MaskImagePixelType);
120     itkGetConstMacro(ForegroundValue, MaskImagePixelType);
121
122     // For common segmentation processes
123     itkSetMacro(MinimalComponentSize, int);
124     itkGetConstMacro(MinimalComponentSize, int);
125     GGO_DefineOption(minSize, SetMinimalComponentSize, int);
126
127     // Step 1 options RemoveAir
128     itkSetMacro(UpperThreshold, InputImagePixelType);
129     itkGetConstMacro(UpperThreshold, InputImagePixelType);
130     GGO_DefineOption(upper, SetUpperThreshold, InputImagePixelType);
131
132     itkSetMacro(NumberOfSlicesToSkipBeforeSearchingSeed, int);
133     itkGetConstMacro(NumberOfSlicesToSkipBeforeSearchingSeed, int);
134     GGO_DefineOption(skipslices, SetNumberOfSlicesToSkipBeforeSearchingSeed, int);
135     
136     itkSetMacro(LowerThreshold, InputImagePixelType);
137     itkGetConstMacro(LowerThreshold, InputImagePixelType);
138     itkSetMacro(UseLowerThreshold, bool);
139     itkGetConstMacro(UseLowerThreshold, bool);
140     itkBooleanMacro(UseLowerThreshold);
141     GGO_DefineOption_WithTest(lower, SetLowerThreshold, InputImagePixelType, UseLowerThreshold);
142
143     void SetLabelizeParameters1(LabelParamType * a) { m_LabelizeParameters1 = a; }
144     itkGetConstMacro(LabelizeParameters1, LabelParamType*);
145     GGO_DefineOption_LabelParam(1, SetLabelizeParameters1, LabelParamType);
146
147     // Step 2 options FindTrachea
148     itkSetMacro(UpperThresholdForTrachea, InputImagePixelType);
149     itkGetConstMacro(UpperThresholdForTrachea, InputImagePixelType);
150     GGO_DefineOption(upperThresholdForTrachea, SetUpperThresholdForTrachea, InputImagePixelType);
151
152     itkSetMacro(MultiplierForTrachea, double);
153     itkGetConstMacro(MultiplierForTrachea, double);
154     GGO_DefineOption(multiplierForTrachea, SetMultiplierForTrachea, double);
155
156     itkSetMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
157     itkGetConstMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
158     GGO_DefineOption(thresholdStepSizeForTrachea, SetThresholdStepSizeForTrachea, InputImagePixelType);
159
160     void AddSeed(InternalIndexType s);
161     std::vector<InternalIndexType> & GetSeeds() { return  m_Seeds; }
162     GGO_DefineOption_Vector(seed, AddSeed, InternalIndexType, ImageType::ImageDimension, true);
163
164     // Step 3 options ExtractLung
165     itkSetMacro(NumberOfHistogramBins, int);
166     itkGetConstMacro(NumberOfHistogramBins, int);
167     GGO_DefineOption(bins, SetNumberOfHistogramBins, int);
168
169     void SetLabelizeParameters2(LabelParamType* a) { m_LabelizeParameters2 = a; }
170     itkGetConstMacro(LabelizeParameters2, LabelParamType*);
171     GGO_DefineOption_LabelParam(2, SetLabelizeParameters2, LabelParamType);
172
173     // Step 4 options RemoveTrachea
174     itkSetMacro(RadiusForTrachea, int);
175     itkGetConstMacro(RadiusForTrachea, int);
176     GGO_DefineOption(radius, SetRadiusForTrachea, int);
177     
178     void SetLabelizeParameters3(LabelParamType * a) { m_LabelizeParameters3 = a; }
179     itkGetConstMacro(LabelizeParameters3, LabelParamType*);
180     GGO_DefineOption_LabelParam(3, SetLabelizeParameters3, LabelParamType);
181
182     // Step 5 final openclose
183     itkSetMacro(FinalOpenClose, bool);
184     itkGetConstMacro(FinalOpenClose, bool);
185     itkBooleanMacro(FinalOpenClose);
186     GGO_DefineOption_Flag(openclose, SetFinalOpenClose);
187
188     itkSetMacro(FinalOpenCloseRadius, int);
189     itkGetConstMacro(FinalOpenCloseRadius, int);
190     GGO_DefineOption(opencloseRadius, SetFinalOpenCloseRadius, int);
191
192   protected:
193     ExtractLungFilter();
194     virtual ~ExtractLungFilter() {}
195
196     // Main members
197     InputImageConstPointer input;
198     MaskImageConstPointer patient;
199     InputImagePointer working_input;
200     typename InternalImageType::Pointer working_image;  
201     typename InternalImageType::Pointer trachea_tmp;
202     MaskImagePointer trachea;
203     MaskImagePointer output;
204     unsigned int m_MaxSeedNumber;
205
206     // Global options
207     itkSetMacro(BackgroundValue, MaskImagePixelType);
208     itkSetMacro(ForegroundValue, MaskImagePixelType);
209     MaskImagePixelType m_PatientMaskBackgroundValue;
210     MaskImagePixelType m_BackgroundValue;
211     MaskImagePixelType m_ForegroundValue;
212     int m_MinimalComponentSize;
213
214     // Step 1
215     InputImagePixelType m_UpperThreshold;
216     InputImagePixelType m_LowerThreshold;
217     bool m_UseLowerThreshold;
218     LabelParamType* m_LabelizeParameters1;
219
220     // Step 2
221     InputImagePixelType m_UpperThresholdForTrachea;
222     InputImagePixelType m_ThresholdStepSizeForTrachea;
223     double m_MultiplierForTrachea;
224     std::vector<InternalIndexType> m_Seeds;
225     int m_NumberOfSlicesToSkipBeforeSearchingSeed;
226
227     // Step 3
228     int m_NumberOfHistogramBins;
229     LabelParamType* m_LabelizeParameters2;
230
231     // Step 4
232     int m_RadiusForTrachea;
233     LabelParamType* m_LabelizeParameters3;
234
235     // Step 5
236     bool m_FinalOpenClose;    
237     int m_FinalOpenCloseRadius;
238
239     // Main functions
240     virtual void GenerateOutputInformation();
241     virtual void GenerateData();
242     
243     // Functions for trachea extraction
244     bool SearchForTracheaSeed(int skip);
245     void SearchForTrachea();
246     void TracheaRegionGrowing();
247     double ComputeTracheaVolume();
248
249   private:
250     ExtractLungFilter(const Self&); //purposely not implemented
251     void operator=(const Self&); //purposely not implemented
252     
253   }; // end class
254   //--------------------------------------------------------------------
255
256 } // end namespace clitk
257 //--------------------------------------------------------------------
258
259 #ifndef ITK_MANUAL_INSTANTIATION
260 #include "clitkExtractLungFilter.txx"
261 #endif
262
263 #endif