]> Creatis software - clitk.git/blob - segmentation/clitkExtractLungFilter.h
c62afe527066816da79fd6bc43c2611bea7c9ed4
[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   //--------------------------------------------------------------------
59 template<class IndexType, class PixelType>
60 class Bifurcation
61 {
62 public:
63   Bifurcation(IndexType _index, PixelType _l, PixelType _l1, PixelType _l2) {
64     index = _index;
65     _l = l;
66     _l1 = l1;
67     _l2 = l2;
68   }
69   IndexType index;
70   PixelType l;
71   PixelType l1;
72   PixelType l2;
73 };
74   //--------------------------------------------------------------------
75
76
77   //--------------------------------------------------------------------
78   template <class TImageType, class TMaskImageType>
79   class ITK_EXPORT ExtractLungFilter: 
80     public clitk::FilterBase, 
81     public itk::ImageToImageFilter<TImageType, TMaskImageType> 
82   {
83     
84   public:
85     /** Standard class typedefs. */
86     typedef itk::ImageToImageFilter<TImageType, TMaskImageType> Superclass;
87     typedef ExtractLungFilter              Self;
88     typedef itk::SmartPointer<Self>        Pointer;
89     typedef itk::SmartPointer<const Self>  ConstPointer;
90     
91     /** Method for creation through the object factory. */
92     itkNewMacro(Self);  
93     
94     /** Run-time type information (and related methods). */
95     itkTypeMacro(ExtractLungFilter, ImageToImageFilter);
96     FILTERBASE_INIT;
97
98     /** Some convenient typedefs */
99     typedef TImageType                       ImageType;
100     typedef typename ImageType::ConstPointer InputImageConstPointer;
101     typedef typename ImageType::Pointer      InputImagePointer;
102     typedef typename ImageType::RegionType   InputImageRegionType; 
103     typedef typename ImageType::PixelType    InputImagePixelType; 
104     typedef typename ImageType::SizeType     InputImageSizeType; 
105     typedef typename ImageType::IndexType    InputImageIndexType; 
106         
107     typedef TMaskImageType                       MaskImageType;
108     typedef typename MaskImageType::ConstPointer MaskImageConstPointer;
109     typedef typename MaskImageType::Pointer      MaskImagePointer;
110     typedef typename MaskImageType::RegionType   MaskImageRegionType; 
111     typedef typename MaskImageType::PixelType    MaskImagePixelType; 
112     typedef typename MaskImageType::SizeType     MaskImageSizeType; 
113     typedef typename MaskImageType::IndexType    MaskImageIndexType; 
114
115     itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
116     typedef int InternalPixelType;
117     typedef itk::Image<InternalPixelType, ImageType::ImageDimension> InternalImageType;
118     typedef typename InternalImageType::Pointer                      InternalImagePointer;
119     typedef typename InternalImageType::IndexType                    InternalIndexType;
120     typedef LabelizeParameters<InternalPixelType>                    LabelParamType;
121     
122     /** Connect inputs */
123     void SetInput(const ImageType * image);
124     void SetInputPatientMask(MaskImageType * mask, MaskImagePixelType BG);
125     itkSetMacro(PatientMaskBackgroundValue, MaskImagePixelType);
126     itkGetConstMacro(PatientMaskBackgroundValue, MaskImagePixelType);
127     GGO_DefineOption(patientBG, SetPatientMaskBackgroundValue, MaskImagePixelType);
128
129     // Set all options at a time
130     template<class ArgsInfoType>
131       void SetArgsInfo(ArgsInfoType arg);
132
133     // Get output (only availabe after update !)
134     typename MaskImageType::Pointer GetTracheaImage() { return trachea; }
135
136     // Background / Foreground
137     itkGetConstMacro(BackgroundValue, MaskImagePixelType);
138     itkGetConstMacro(ForegroundValue, MaskImagePixelType);
139
140     // For common segmentation processes
141     itkSetMacro(MinimalComponentSize, int);
142     itkGetConstMacro(MinimalComponentSize, int);
143     GGO_DefineOption(minSize, SetMinimalComponentSize, int);
144
145     // Step 1 options RemoveAir
146     itkSetMacro(UpperThreshold, InputImagePixelType);
147     itkGetConstMacro(UpperThreshold, InputImagePixelType);
148     GGO_DefineOption(upper, SetUpperThreshold, InputImagePixelType);
149
150     itkSetMacro(LowerThreshold, InputImagePixelType);
151     itkGetConstMacro(LowerThreshold, InputImagePixelType);
152     itkSetMacro(UseLowerThreshold, bool);
153     itkGetConstMacro(UseLowerThreshold, bool);
154     itkBooleanMacro(UseLowerThreshold);
155     GGO_DefineOption_WithTest(lower, SetLowerThreshold, InputImagePixelType, UseLowerThreshold);
156
157     void SetLabelizeParameters1(LabelParamType * a) { m_LabelizeParameters1 = a; }
158     itkGetConstMacro(LabelizeParameters1, LabelParamType*);
159     GGO_DefineOption_LabelParam(1, SetLabelizeParameters1, LabelParamType);
160
161     // Step 2 options FindTrachea
162     itkSetMacro(UpperThresholdForTrachea, InputImagePixelType);
163     itkGetConstMacro(UpperThresholdForTrachea, InputImagePixelType);
164     GGO_DefineOption(upperThresholdForTrachea, SetUpperThresholdForTrachea, InputImagePixelType);
165
166     itkSetMacro(MultiplierForTrachea, double);
167     itkGetConstMacro(MultiplierForTrachea, double);
168     GGO_DefineOption(multiplierForTrachea, SetMultiplierForTrachea, double);
169
170     itkSetMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
171     itkGetConstMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
172     GGO_DefineOption(thresholdStepSizeForTrachea, SetThresholdStepSizeForTrachea, InputImagePixelType);
173
174     void AddSeed(InternalIndexType s);
175     std::vector<InternalIndexType> & GetSeeds() { return  m_Seeds; }
176     GGO_DefineOption_Vector(seed, AddSeed, InternalIndexType, ImageType::ImageDimension, true);
177
178     // Step 3 options ExtractLung
179     itkSetMacro(NumberOfHistogramBins, int);
180     itkGetConstMacro(NumberOfHistogramBins, int);
181     GGO_DefineOption(bins, SetNumberOfHistogramBins, int);
182
183     void SetLabelizeParameters2(LabelParamType* a) { m_LabelizeParameters2 = a; }
184     itkGetConstMacro(LabelizeParameters2, LabelParamType*);
185     GGO_DefineOption_LabelParam(2, SetLabelizeParameters2, LabelParamType);
186
187     // Step 4 options RemoveTrachea
188     itkSetMacro(RadiusForTrachea, int);
189     itkGetConstMacro(RadiusForTrachea, int);
190     GGO_DefineOption(radius, SetRadiusForTrachea, int);
191     
192     void SetLabelizeParameters3(LabelParamType * a) { m_LabelizeParameters3 = a; }
193     itkGetConstMacro(LabelizeParameters3, LabelParamType*);
194     GGO_DefineOption_LabelParam(3, SetLabelizeParameters3, LabelParamType);
195
196     // Step 5 options LungSeparation
197     //     itkSetMacro(FinalOpenClose, bool);
198     //     itkGetConstMacro(FinalOpenClose, bool);
199     //     itkBooleanMacro(FinalOpenClose);
200
201     // Bronchial bifurcations
202     itkSetMacro(FindBronchialBifurcations, bool);
203     itkGetConstMacro(FindBronchialBifurcations, bool);
204     itkBooleanMacro(FindBronchialBifurcations);
205
206   protected:
207     ExtractLungFilter();
208     virtual ~ExtractLungFilter() {}
209
210     // Main members
211     InputImageConstPointer input;
212     MaskImageConstPointer patient;
213     InputImagePointer working_input;
214     typename InternalImageType::Pointer working_image;  
215     typename InternalImageType::Pointer trachea_tmp;
216     MaskImagePointer trachea;
217     MaskImagePointer output;
218     unsigned int m_MaxSeedNumber;
219
220     // Global options
221     itkSetMacro(BackgroundValue, MaskImagePixelType);
222     itkSetMacro(ForegroundValue, MaskImagePixelType);
223     MaskImagePixelType m_PatientMaskBackgroundValue;
224     MaskImagePixelType m_BackgroundValue;
225     MaskImagePixelType m_ForegroundValue;
226     int m_MinimalComponentSize;
227
228     // Step 1
229     InputImagePixelType m_UpperThreshold;
230     InputImagePixelType m_LowerThreshold;
231     bool m_UseLowerThreshold;
232     LabelParamType* m_LabelizeParameters1;
233
234     // Step 2
235     InputImagePixelType m_UpperThresholdForTrachea;
236     InputImagePixelType m_ThresholdStepSizeForTrachea;
237     double m_MultiplierForTrachea;
238     std::vector<InternalIndexType> m_Seeds;
239
240     // Step 3
241     int m_NumberOfHistogramBins;
242     LabelParamType* m_LabelizeParameters2;
243
244     // Step 4
245     int m_RadiusForTrachea;
246     LabelParamType* m_LabelizeParameters3;
247
248     // Step 5
249     //     bool m_FinalOpenClose;
250     
251     bool m_FindBronchialBifurcations;
252     
253     virtual void GenerateOutputInformation();
254     virtual void GenerateData();
255
256     typedef Bifurcation<MaskImageIndexType,MaskImagePixelType> BifurcationType;
257     void TrackFromThisIndex(std::vector<BifurcationType> & listOfBifurcations, 
258                             MaskImagePointer skeleton, 
259                             MaskImageIndexType index,
260                             MaskImagePixelType label);
261         
262   private:
263     ExtractLungFilter(const Self&); //purposely not implemented
264     void operator=(const Self&); //purposely not implemented
265     
266   }; // end class
267   //--------------------------------------------------------------------
268
269 } // end namespace clitk
270 //--------------------------------------------------------------------
271
272 #ifndef ITK_MANUAL_INSTANTIATION
273 #include "clitkExtractLungFilter.txx"
274 #endif
275
276 #endif