]> Creatis software - clitk.git/blob - segmentation/clitkExtractLungFilter.h
Add output dicom filename to clitkImage2Dicom
[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     itkSetMacro(TracheaSeedAlgorithm, int);
147     itkGetConstMacro(TracheaSeedAlgorithm, int);
148
149     // Step 2 options FindTrachea
150     itkSetMacro(UpperThresholdForTrachea, InputImagePixelType);
151     itkGetConstMacro(UpperThresholdForTrachea, InputImagePixelType);
152
153     itkSetMacro(MultiplierForTrachea, double);
154     itkGetConstMacro(MultiplierForTrachea, double);
155
156     itkSetMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
157     itkGetConstMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
158
159     // options FindTrachea2
160     itkSetMacro(NumSlices, int);
161     itkGetConstMacro(NumSlices, int);
162     itkSetMacro(MaxElongation, double);
163     itkGetConstMacro(MaxElongation, double);
164     itkSetMacro(SeedPreProcessingThreshold, int);
165     itkGetConstMacro(SeedPreProcessingThreshold, int);
166
167     void AddSeedInPixels(InternalIndexType s);
168     void AddSeed(InputImagePointType s);
169     std::vector<InternalIndexType> & GetSeeds() { return  m_Seeds; }
170
171     itkSetMacro(TracheaVolumeMustBeCheckedFlag, bool);
172     itkGetConstMacro(TracheaVolumeMustBeCheckedFlag, bool);
173     itkBooleanMacro(TracheaVolumeMustBeCheckedFlag);    
174
175     itkSetMacro(VerboseRegionGrowingFlag, bool);
176     itkGetConstMacro(VerboseRegionGrowingFlag, bool);
177     itkBooleanMacro(VerboseRegionGrowingFlag);    
178
179     itkSetMacro(RemoveSmallLabelBeforeSeparationFlag, bool);
180     itkGetConstMacro(RemoveSmallLabelBeforeSeparationFlag, bool);
181     itkBooleanMacro(RemoveSmallLabelBeforeSeparationFlag);    
182
183     // Step 3 options ExtractLung
184     itkSetMacro(NumberOfHistogramBins, int);
185     itkGetConstMacro(NumberOfHistogramBins, int);
186
187     void SetLabelizeParameters2(LabelParamType* a) { m_LabelizeParameters2 = a; }
188     itkGetConstMacro(LabelizeParameters2, LabelParamType*);
189
190     // Step 4 options RemoveTrachea
191     itkSetMacro(RadiusForTrachea, int);
192     itkGetConstMacro(RadiusForTrachea, int);
193     
194     void SetLabelizeParameters3(LabelParamType * a) { m_LabelizeParameters3 = a; }
195     itkGetConstMacro(LabelizeParameters3, LabelParamType*);
196
197     // Step 5 final openclose
198     itkSetMacro(OpenCloseFlag, bool);
199     itkGetConstMacro(OpenCloseFlag, bool);
200     itkBooleanMacro(OpenCloseFlag);
201
202     itkSetMacro(OpenCloseRadius, int);
203     itkGetConstMacro(OpenCloseRadius, int);
204     
205     // Step 6 fill holes
206     itkSetMacro(FillHolesFlag, bool);
207     itkGetConstMacro(FillHolesFlag, bool);
208     itkBooleanMacro(FillHolesFlag);
209
210     // Separate lungs
211     itkSetMacro(SeparateLungsFlag, bool);
212     itkGetConstMacro(SeparateLungsFlag, bool);
213     itkBooleanMacro(SeparateLungsFlag);
214
215     // Step Auto Crop
216     itkSetMacro(AutoCrop, bool);
217     itkGetConstMacro(AutoCrop, bool);
218     itkBooleanMacro(AutoCrop);
219     
220   protected:
221     ExtractLungFilter();
222     virtual ~ExtractLungFilter() {}
223
224     // Main members
225     InputImageConstPointer input;
226     MaskImagePointer patient;
227     InputImagePointer working_input;
228     std::string m_OutputLungFilename;
229     std::string m_OutputTracheaFilename;
230     MaskImagePointer working_mask;  
231     MaskImagePointer trachea;
232     unsigned int m_MaxSeedNumber;
233
234     // Global options
235     itkSetMacro(BackgroundValue, MaskImagePixelType);
236     itkSetMacro(ForegroundValue, MaskImagePixelType);
237     MaskImagePixelType m_PatientMaskBackgroundValue;
238     MaskImagePixelType m_BackgroundValue;
239     MaskImagePixelType m_ForegroundValue;
240     int m_MinimalComponentSize;
241     bool m_AutoCrop;
242     bool m_RemoveSmallLabelBeforeSeparationFlag;
243
244     // Step 1
245     InputImagePixelType m_UpperThreshold;
246     InputImagePixelType m_LowerThreshold;
247     bool m_UseLowerThreshold;
248     LabelParamType* m_LabelizeParameters1;
249
250     // Step 2
251     int m_TracheaSeedAlgorithm;
252     InputImagePixelType m_UpperThresholdForTrachea;
253     InputImagePixelType m_ThresholdStepSizeForTrachea;
254     double m_MultiplierForTrachea;
255     std::vector<InternalIndexType> m_Seeds;
256     std::vector<InputImagePointType> m_SeedsInMM;
257     int m_NumberOfSlicesToSkipBeforeSearchingSeed;
258     bool m_TracheaVolumeMustBeCheckedFlag;
259     bool m_VerboseRegionGrowingFlag;
260     int m_NumSlices;
261     double m_MaxElongation;
262     int m_SeedPreProcessingThreshold;
263
264     // Step 3
265     int m_NumberOfHistogramBins;
266     LabelParamType* m_LabelizeParameters2;
267
268     // Step 4
269     int m_RadiusForTrachea;
270     LabelParamType* m_LabelizeParameters3;
271
272     // Step 5
273     bool m_OpenCloseFlag;    
274     int m_OpenCloseRadius;
275
276     // Step 6
277     bool m_FillHolesFlag;    
278     InputImageSizeType m_FillHolesDirections;
279
280     bool m_SeparateLungsFlag;
281     
282     // Main functions
283     virtual void GenerateOutputInformation();
284     virtual void GenerateInputRequestedRegion();
285     virtual void GenerateData();
286     
287     // Functions for trachea extraction
288     bool SearchForTracheaSeed(int skip);
289     bool SearchForTracheaSeed2(int numberOfSlices);
290     void SearchForTrachea();
291     void TracheaRegionGrowing();
292     double ComputeTracheaVolume();
293
294   private:
295     ExtractLungFilter(const Self&); //purposely not implemented
296     void operator=(const Self&); //purposely not implemented
297     
298   }; // end class
299   //--------------------------------------------------------------------
300
301 } // end namespace clitk
302 //--------------------------------------------------------------------
303
304 #ifndef ITK_MANUAL_INSTANTIATION
305 #include "clitkExtractLungFilter.txx"
306 #endif
307
308 #endif