]> Creatis software - clitk.git/blob - segmentation/clitkExtractBonesFilter.txx
change "SegFunction" to "SegUtils"
[clitk.git] / segmentation / clitkExtractBonesFilter.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 CLITKEXTRACTBONESSFILTER_TXX
20 #define CLITKEXTRACTBONESSFILTER_TXX
21
22 // clitk
23 #include "clitkImageCommon.h"
24 #include "clitkSetBackgroundImageFilter.h"
25 #include "clitkSegmentationUtils.h"
26 #include "clitkAutoCropFilter.h"
27
28 // itk
29 #include "itkBinaryThresholdImageFilter.h"
30 #include "itkConnectedComponentImageFilter.h"
31 #include "itkRelabelComponentImageFilter.h"
32 #include "itkNeighborhoodConnectedImageFilter.h"
33
34 //--------------------------------------------------------------------
35 template <class TInputImageType, class TOutputImageType>
36 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
37 ExtractBonesFilter():
38   clitk::FilterBase(),
39   itk::ImageToImageFilter<TInputImageType, TOutputImageType>()
40 {
41   // Default global options
42   this->SetNumberOfRequiredInputs(1);
43   SetBackgroundValue(0); // Must be zero
44   SetForegroundValue(1);
45
46   SetMinimalComponentSize(100);
47   SetUpperThreshold1(1500);
48   SetLowerThreshold1(100);
49   SetFullConnectivity(false);
50
51   SetUpperThreshold2(1500);
52   SetLowerThreshold2(10);
53   InputImageSizeType s;
54   s.Fill(1);
55   SetRadius2(s);
56   SetSampleRate2(0);
57   AutoCropOff();
58 }
59 //--------------------------------------------------------------------
60
61
62 //--------------------------------------------------------------------
63 template <class TInputImageType, class TOutputImageType>
64 void 
65 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
66 SetInput(const TInputImageType * image) 
67 {
68   this->SetNthInput(0, const_cast<TInputImageType *>(image));
69 }
70 //--------------------------------------------------------------------
71
72
73 //--------------------------------------------------------------------
74 template <class TInputImageType, class TOutputImageType>
75 template<class ArgsInfoType>
76 void 
77 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
78 SetArgsInfo(ArgsInfoType mArgsInfo)
79 {
80   SetVerboseOption_GGO(mArgsInfo);
81   SetVerboseStep_GGO(mArgsInfo);
82   SetWriteStep_GGO(mArgsInfo);
83   SetVerboseWarningOff_GGO(mArgsInfo);
84
85   SetMinimalComponentSize_GGO(mArgsInfo);
86   SetUpperThreshold1_GGO(mArgsInfo);
87   SetLowerThreshold1_GGO(mArgsInfo);
88   SetFullConnectivity_GGO(mArgsInfo);
89
90   SetUpperThreshold2_GGO(mArgsInfo);
91   SetLowerThreshold2_GGO(mArgsInfo);
92   SetRadius2_GGO(mArgsInfo);
93   SetSampleRate2_GGO(mArgsInfo);
94   SetAutoCrop_GGO(mArgsInfo);
95 }
96 //--------------------------------------------------------------------
97
98
99 //--------------------------------------------------------------------
100 template <class TInputImageType, class TOutputImageType>
101 void 
102 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
103 GenerateOutputInformation() { 
104   // Get input pointers
105   InputImagePointer input   = dynamic_cast<TInputImageType*>(itk::ProcessObject::GetInput(0));
106   //  InputImagePointer input = dynamic_cast<TInputImageType*>(itk::ProcessObject::GetInput(0));
107   Superclass::GenerateOutputInformation();
108   OutputImagePointer outputImage = this->GetOutput(0);
109   outputImage->SetRegions(input->GetLargestPossibleRegion());
110
111   // typedefs
112   typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinarizeFilterType;
113   typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> BinarizeFilterType;
114   typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
115   typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
116   typedef clitk::SetBackgroundImageFilter<InternalImageType,InternalImageType, InternalImageType> SetBackgroundFilterType; 
117   typedef itk::CastImageFilter<InternalImageType,OutputImageType> CastImageFilterType; 
118   typedef itk::ImageFileWriter<OutputImageType> WriterType; 
119
120   //--------------------------------------------------------------------
121   //--------------------------------------------------------------------
122   StartNewStep("Initial Labeling");
123
124   typename InternalImageType::Pointer firstLabelImage;
125     
126   //---------------------------------
127   // Binarize the image
128   //---------------------------------
129   typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
130   binarizeFilter->SetInput(input);
131   binarizeFilter->SetLowerThreshold(GetLowerThreshold1());
132   binarizeFilter->SetUpperThreshold(GetUpperThreshold1());
133   binarizeFilter->SetInsideValue(this->GetForegroundValue());
134   binarizeFilter->SetOutsideValue(this->GetBackgroundValue());
135
136   //---------------------------------
137   // Label the connected components
138   //---------------------------------
139   typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
140   connectFilter->SetInput(binarizeFilter->GetOutput());
141   connectFilter->SetBackgroundValue(this->GetBackgroundValue());
142   connectFilter->SetFullyConnected(GetFullConnectivity());
143
144   //---------------------------------
145   // Sort the labels according to size
146   //---------------------------------
147   typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
148   relabelFilter->SetInput(connectFilter->GetOutput());
149   relabelFilter->SetMinimumObjectSize(GetMinimalComponentSize());
150     
151   //---------------------------------
152   // Keep the label
153   //---------------------------------
154   typename BinarizeFilterType::Pointer binarizeFilter2=BinarizeFilterType::New();
155   binarizeFilter2->SetInput(relabelFilter->GetOutput());
156   binarizeFilter2->SetLowerThreshold(1);
157   binarizeFilter2->SetUpperThreshold(1);
158   binarizeFilter2->SetInsideValue(this->GetForegroundValue());
159   binarizeFilter2->SetOutsideValue(this->GetBackgroundValue());
160   binarizeFilter2->Update();
161
162   firstLabelImage = binarizeFilter2->GetOutput();
163
164   //--------------------------------------------------------------------
165   //--------------------------------------------------------------------
166   StartNewStep("Neighborhood connected filter");
167   typename InternalImageType::Pointer secondLabelImage;
168     
169   //---------------------------------
170   //Neighborhood connected RG 
171   //---------------------------------
172   typedef itk::NeighborhoodConnectedImageFilter<InputImageType, InternalImageType> 
173     NeighborhoodConnectedImageFilterType;
174   typename NeighborhoodConnectedImageFilterType::Pointer neighborhoodConnectedImageFilter= 
175     NeighborhoodConnectedImageFilterType::New();
176   
177   // thresholds
178   neighborhoodConnectedImageFilter->SetLower(GetLowerThreshold2());
179   neighborhoodConnectedImageFilter->SetUpper(GetUpperThreshold2());
180   neighborhoodConnectedImageFilter->SetReplaceValue(this->GetForegroundValue());
181   neighborhoodConnectedImageFilter->SetRadius(GetRadius2());
182   neighborhoodConnectedImageFilter->SetInput(input);
183
184   // Seeds from label image
185   typedef itk::ImageRegionIteratorWithIndex<InternalImageType> IteratorType;
186   IteratorType it(firstLabelImage, firstLabelImage->GetLargestPossibleRegion());
187   typename InputImageType::IndexType index;
188   unsigned int counter=0;
189   while (!it.IsAtEnd())
190     {
191       if (it.Get()==this->GetForegroundValue())
192         {
193           counter++;
194           index=it.GetIndex();
195           neighborhoodConnectedImageFilter->AddSeed(index);
196           ++it;
197           unsigned int i=0;
198           while (!it.IsAtEnd()  &&  i< (unsigned int) GetSampleRate2())
199             {        
200               ++it;
201               i++;
202             }
203         }
204       else ++it;
205     }
206
207   neighborhoodConnectedImageFilter->Update();
208   secondLabelImage = neighborhoodConnectedImageFilter->GetOutput();
209
210   //--------------------------------------------------------------------
211   //--------------------------------------------------------------------
212   StartNewStep("Combine de images");
213   typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> 
214     SetBackgroundImageFilterType;
215   typename SetBackgroundImageFilterType::Pointer setBackgroundFilter=SetBackgroundImageFilterType::New();
216   setBackgroundFilter->SetInput(firstLabelImage);
217   setBackgroundFilter->SetInput2(secondLabelImage);
218   setBackgroundFilter->SetMaskValue(this->GetForegroundValue());
219   setBackgroundFilter->SetOutsideValue(this->GetForegroundValue());
220   setBackgroundFilter->Update();
221
222   output = setBackgroundFilter->GetOutput();
223
224   //--------------------------------------------------------------------
225   //--------------------------------------------------------------------
226   // [Optional]
227   if (GetAutoCrop()) {
228     StartNewStep("AutoCrop");
229     typedef clitk::AutoCropFilter<InternalImageType> CropFilterType;
230     typename CropFilterType::Pointer cropFilter = CropFilterType::New();
231     cropFilter->SetInput(output);
232     cropFilter->SetBackgroundValue(GetBackgroundValue());
233     cropFilter->Update();   
234     output = cropFilter->GetOutput();
235     StopCurrentStep<InternalImageType>(output);
236     outputImage->SetRegions(output->GetLargestPossibleRegion());
237   }
238
239 }
240 //--------------------------------------------------------------------
241
242
243 //--------------------------------------------------------------------
244 template <class TInputImageType, class TOutputImageType>
245 void 
246 clitk::ExtractBonesFilter<TInputImageType, TOutputImageType>::
247 GenerateData() {
248
249   //--------------------------------------------------------------------
250   //--------------------------------------------------------------------
251   // Final Cast 
252   typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
253   typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
254   caster->SetInput(output);
255   caster->Update();
256   //this->SetNthOutput(0, caster->GetOutput());
257   this->GraftOutput(caster->GetOutput());
258   return;
259 }
260 //--------------------------------------------------------------------
261
262   
263 #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX