]> Creatis software - clitk.git/blob - segmentation/clitkExtractPatientFilter.txx
some segmentation tools (most from jef)
[clitk.git] / segmentation / clitkExtractPatientFilter.txx
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 CLITKEXTRACTPATIENTFILTER_TXX
20 #define CLITKEXTRACTPATIENTFILTER_TXX
21
22 // clitk
23 #include "clitkImageCommon.h"
24 #include "clitkSetBackgroundImageFilter.h"
25 #include "clitkDecomposeAndReconstructImageFilter.h"
26 #include "clitkAutoCropFilter.h"
27
28 // itk
29 #include "itkBinaryThresholdImageFilter.h"
30 #include "itkConnectedComponentImageFilter.h"
31 #include "itkRelabelComponentImageFilter.h"
32 #include "itkBinaryMorphologicalClosingImageFilter.h"
33 #include "itkBinaryMorphologicalOpeningImageFilter.h"
34 #include "itkBinaryBallStructuringElement.h"
35 #include "itkCastImageFilter.h"
36
37 //--------------------------------------------------------------------
38 template <class TInputImageType, class TOutputImageType>
39 clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
40 ExtractPatientFilter():
41   clitk::FilterBase(),
42   itk::ImageToImageFilter<TInputImageType, TOutputImageType>()
43 {
44   this->SetNumberOfRequiredInputs(1);
45   SetBackgroundValue(0); // Must be zero
46   SetForegroundValue(1);
47
48   // Step 1: Threshold + CC + sort (Find low density areas)
49   SetUpperThreshold(-300);
50   SetLowerThreshold(-1000);
51   UseLowerThresholdOff();
52
53   // Step 2: DecomposeAndReconstructImageFilter (optional)
54   DecomposeAndReconstructDuringFirstStepOff();
55   InternalImageSizeType r;
56   r.Fill(1);
57   SetRadius1(r);
58   SetMaximumNumberOfLabels1(2);
59   SetNumberOfNewLabels1(1);
60
61   // Step 3: Remove the air (largest area).
62
63   // Step 4: 2nd DecomposeAndReconstructImageFilter
64   DecomposeAndReconstructDuringSecondStepOff();
65   SetRadius2(r);
66   SetMaximumNumberOfLabels2(2);
67   SetNumberOfNewLabels2(1);
68   
69   // Step 5: Only keep label corresponding (Keep patient's labels)
70   SetFirstKeep(1);
71   SetLastKeep(1);
72   
73   // Step 4: OpenClose (option)
74   FinalOpenCloseOn();
75   AutoCropOff();
76 }
77 //--------------------------------------------------------------------
78
79
80 //--------------------------------------------------------------------
81 template <class TInputImageType, class TOutputImageType>
82 void 
83 clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
84 SetInput(const TInputImageType * image) 
85 {
86   this->SetNthInput(0, const_cast<TInputImageType *>(image));
87 }
88 //--------------------------------------------------------------------
89
90
91 //--------------------------------------------------------------------
92 template <class TInputImageType, class TOutputImageType>
93 template<class ArgsInfoType>
94 void 
95 clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
96 SetArgsInfo(ArgsInfoType arg)
97 {
98   SetVerboseOption_GGO(arg);
99   SetVerboseStep_GGO(arg);
100   SetWriteStep_GGO(arg);
101   SetVerboseWarningOff_GGO(arg);
102
103   SetUpperThreshold_GGO(arg);
104   SetLowerThreshold_GGO(arg);
105
106   SetDecomposeAndReconstructDuringFirstStep_GGO(arg);
107   SetRadius1_GGO(arg);
108   SetMaximumNumberOfLabels1_GGO(arg);
109   SetNumberOfNewLabels1_GGO(arg);
110
111   SetDecomposeAndReconstructDuringSecondStep_GGO(arg);
112   SetRadius2_GGO(arg);
113   SetMaximumNumberOfLabels2_GGO(arg);
114   SetNumberOfNewLabels2_GGO(arg);
115   
116   SetFirstKeep_GGO(arg);
117   SetLastKeep_GGO(arg);
118
119   SetFinalOpenClose_GGO(arg);
120   SetAutoCrop_GGO(arg);
121 }
122 //--------------------------------------------------------------------
123
124
125 //--------------------------------------------------------------------
126 template <class TInputImageType, class TOutputImageType>
127 void 
128 clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
129 GenerateOutputInformation() { 
130
131   Superclass::GenerateOutputInformation();
132   input = dynamic_cast<const TInputImageType*>(itk::ProcessObject::GetInput(0));
133
134   // OutputImagePointer outputImage = this->GetOutput(0);
135 //   outputImage->SetRegions(input->GetLargestPossibleRegion());
136
137   // Get input pointers
138   static const unsigned int Dim = InputImageType::ImageDimension;
139   //input = dynamic_cast<const TInputImageType*>(itk::ProcessObject::GetInput(0));
140     
141   //--------------------------------------------------------------------
142   //--------------------------------------------------------------------
143   // Step 1: 
144   StartNewStep("Find low densities areas");
145   typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> BinarizeFilterType;  
146   typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New();
147   binarizeFilter->SetInput(input);
148   if (m_UseLowerThreshold) binarizeFilter->SetLowerThreshold(GetLowerThreshold());
149   binarizeFilter->SetUpperThreshold(GetUpperThreshold());
150   binarizeFilter ->SetInsideValue(this->GetForegroundValue());
151   binarizeFilter ->SetOutsideValue(this->GetBackgroundValue());
152
153   // Connected component labeling
154   typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
155   typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
156   connectFilter->SetInput(binarizeFilter->GetOutput());
157   connectFilter->SetBackgroundValue(this->GetBackgroundValue());
158   connectFilter->SetFullyConnected(false);
159   
160   // Sort labels according to size
161   typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
162   typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
163   relabelFilter->InPlaceOn();
164   relabelFilter->SetInput(connectFilter->GetOutput());
165   relabelFilter->Update();
166   working_image = relabelFilter->GetOutput();
167   
168   // End
169   StopCurrentStep<InternalImageType>(working_image);
170
171   //--------------------------------------------------------------------
172   //--------------------------------------------------------------------
173   // [Optional] 
174   if (GetDecomposeAndReconstructDuringFirstStep()) {
175     StartNewStep("First Decompose & Reconstruct step");
176     typedef clitk::DecomposeAndReconstructImageFilter<InternalImageType,InternalImageType> FilterType;
177     typename FilterType::Pointer f = FilterType::New();
178     f->SetInput(working_image);
179     // f->SetVerbose(m_Verbose);
180     f->SetRadius(GetRadius1());
181     f->SetMaximumNumberOfLabels(GetMaximumNumberOfLabels1());
182     f->SetBackgroundValue(this->GetBackgroundValue());
183     f->SetForegroundValue(this->GetForegroundValue());
184     f->SetFullyConnected(true);
185     f->SetNumberOfNewLabels(GetNumberOfNewLabels1());
186     f->Update();
187     working_image = f->GetOutput();
188     StopCurrentStep<InternalImageType>(working_image);
189   }
190   
191   //--------------------------------------------------------------------
192   //--------------------------------------------------------------------
193   StartNewStep("Remove the air (largest area)");
194   typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> iBinarizeFilterType;  
195   typename iBinarizeFilterType::Pointer binarizeFilter2 = iBinarizeFilterType::New();
196   binarizeFilter2->SetInput(working_image);
197   binarizeFilter2->SetLowerThreshold(this->GetForegroundValue());
198   binarizeFilter2->SetUpperThreshold(this->GetForegroundValue());
199   binarizeFilter2 ->SetInsideValue(this->GetBackgroundValue());
200   binarizeFilter2 ->SetOutsideValue(this->GetForegroundValue());
201   //  binarizeFilter2 ->Update(); // NEEDED ?
202
203   typename ConnectFilterType::Pointer connectFilter2 = ConnectFilterType::New();
204   connectFilter2->SetInput(binarizeFilter2->GetOutput());
205   connectFilter2->SetBackgroundValue(this->GetBackgroundValue());
206   connectFilter2->SetFullyConnected(false);
207
208   typename RelabelFilterType::Pointer relabelFilter2 = RelabelFilterType::New();
209   relabelFilter2->SetInput(connectFilter2->GetOutput());
210   relabelFilter2->Update();
211   working_image = relabelFilter2->GetOutput();
212   StopCurrentStep<InternalImageType>(working_image);
213
214   //--------------------------------------------------------------------
215   //--------------------------------------------------------------------
216   // [Optional] 
217   if (GetDecomposeAndReconstructDuringSecondStep()) {
218     StartNewStep("Second Decompose & Reconstruct step");
219     typedef clitk::DecomposeAndReconstructImageFilter<InternalImageType,InternalImageType> FilterType;
220     typename FilterType::Pointer f = FilterType::New();
221     f->SetInput(working_image);
222     // f->SetVerbose(m_Verbose);
223     f->SetRadius(GetRadius2());
224     f->SetMaximumNumberOfLabels(GetMaximumNumberOfLabels2());
225     f->SetBackgroundValue(this->GetBackgroundValue());
226     f->SetForegroundValue(this->GetForegroundValue());
227     f->SetFullyConnected(true);
228     f->SetNumberOfNewLabels(GetNumberOfNewLabels2());
229     f->Update();
230     working_image = f->GetOutput();
231     StopCurrentStep<InternalImageType>(working_image);
232   }
233
234   //--------------------------------------------------------------------
235   //--------------------------------------------------------------------
236   StartNewStep("Keep patient's labels");
237   typename iBinarizeFilterType::Pointer binarizeFilter3 = iBinarizeFilterType::New();
238   binarizeFilter3->SetInput(working_image);
239   binarizeFilter3->SetLowerThreshold(GetFirstKeep());
240   binarizeFilter3->SetUpperThreshold(GetLastKeep());
241   binarizeFilter3 ->SetInsideValue(this->GetForegroundValue());
242   binarizeFilter3 ->SetOutsideValue(this->GetBackgroundValue());
243   binarizeFilter3->Update();
244   working_image = binarizeFilter3->GetOutput();
245   StopCurrentStep<InternalImageType>(working_image);
246   
247   //--------------------------------------------------------------------
248   //--------------------------------------------------------------------
249   // [Optional]
250   if (GetFinalOpenClose()) {
251     StartNewStep("Final OpenClose");
252     // Open
253     typedef itk::BinaryBallStructuringElement<InternalPixelType,Dim> KernelType;
254     KernelType structuringElement;
255     structuringElement.SetRadius(1);
256     structuringElement.CreateStructuringElement();
257     typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> OpenFilterType;
258     typename OpenFilterType::Pointer openFilter = OpenFilterType::New();
259     openFilter->SetInput(working_image);
260     openFilter->SetBackgroundValue(this->GetBackgroundValue());
261     openFilter->SetForegroundValue(this->GetForegroundValue());
262     openFilter->SetKernel(structuringElement);  
263     // Close
264     typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> CloseFilterType;
265     typename CloseFilterType::Pointer closeFilter = CloseFilterType::New();
266     closeFilter->SetInput(openFilter->GetOutput());
267     closeFilter->SetSafeBorder(true);
268     closeFilter->SetForegroundValue(this->GetForegroundValue());
269     //  closeFilter->SetBackgroundValue(SetBackgroundValue());
270     closeFilter->SetKernel(structuringElement);
271     closeFilter->Update();  
272     working_image = closeFilter->GetOutput();
273     StopCurrentStep<InternalImageType>(working_image);
274   }
275
276   //--------------------------------------------------------------------
277   //--------------------------------------------------------------------
278   // Final Cast 
279   typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
280   typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
281   caster->SetInput(working_image);
282   caster->Update();
283   output = caster->GetOutput();
284
285   //--------------------------------------------------------------------
286   //--------------------------------------------------------------------
287   // [Optional]
288   if (GetAutoCrop()) {
289   StartNewStep("AutoCrop");
290     typedef clitk::AutoCropFilter<OutputImageType> CropFilterType;
291     typename CropFilterType::Pointer cropFilter = CropFilterType::New();
292     cropFilter->SetInput(output);
293     cropFilter->SetBackgroundValue(GetBackgroundValue());
294     cropFilter->Update();   
295     output = cropFilter->GetOutput();
296     StopCurrentStep<OutputImageType>(output);
297   }
298 }
299 //--------------------------------------------------------------------
300
301
302 //--------------------------------------------------------------------
303 template <class TInputImageType, class TOutputImageType>
304 void 
305 clitk::ExtractPatientFilter<TInputImageType, TOutputImageType>::
306 GenerateData() {
307   //this->SetNthOutput(0, output); // -> no because redo filter otherwise
308   this->GraftOutput(output);
309 }
310 //--------------------------------------------------------------------
311   
312
313 #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX