]> Creatis software - clitk.git/blob - itk/clitkDecomposeThroughErosionImageFilter.txx
changes in license header
[clitk.git] / itk / clitkDecomposeThroughErosionImageFilter.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://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 #ifndef clitkDecomposeThroughErosionImageFilter_txx
19 #define clitkDecomposeThroughErosionImageFilter_txx
20
21 /* =================================================
22  * @file   clitkDecomposeThroughErosionImageFilter.txx
23  * @author 
24  * @date   
25  * 
26  * @brief 
27  * 
28  ===================================================*/
29
30
31 namespace clitk
32 {
33
34   //-------------------------------------------------------------------
35   // Update with the number of dimensions
36   //-------------------------------------------------------------------
37   template<class InputImageType, class OutputImageType>
38   DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::DecomposeThroughErosionImageFilter()
39   {
40    m_Verbose=false;
41    m_Lower =1;
42    m_Upper=1;
43    m_Inside=1;
44    m_Outside=0;
45    m_ErosionPaddingValue=static_cast<OutputPixelType>(-1);
46    for (unsigned int i=0; i<InputImageDimension; i++)
47      m_Radius[i]=1;
48    m_NumberOfNewLabels=1;
49    m_FullyConnected=true;
50    m_MinimumObjectSize=10;
51    m_MinimumNumberOfIterations=1;
52   }
53
54
55   //-------------------------------------------------------------------
56   // Update with the number of dimensions and the pixeltype
57   //-------------------------------------------------------------------
58   template<class InputImageType, class  OutputImageType> 
59   void 
60   DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::GenerateData()
61   {
62
63     //---------------------------------
64     // Typedefs 
65     //--------------------------------- 
66
67     // Internal type
68     typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
69
70     // Filters used
71     typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinaryThresholdImageFilter;
72     typedef itk::BinaryBallStructuringElement<InputPixelType,InputImageDimension > KernelType;
73     typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> BinaryErodeImageFilterType;
74     typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> BinaryThresholdImageFilterType;
75     typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
76     typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
77     typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelImageFilterType;
78     typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> SetBackgroundImageFilterType;
79   
80     //---------------------------------
81     // Binarize input
82     //--------------------------------- 
83     typename  InputBinaryThresholdImageFilter::Pointer inputBinarizer=InputBinaryThresholdImageFilter::New();
84     inputBinarizer->SetInput(this->GetInput());
85     inputBinarizer->SetLowerThreshold(m_Lower);
86     inputBinarizer->SetUpperThreshold(m_Upper);
87     inputBinarizer ->SetInsideValue(m_Inside);
88     inputBinarizer ->SetOutsideValue(m_Outside);
89     if(m_Verbose) std::cout<<"Binarizing the input..."<<std::endl;
90     inputBinarizer->Update();
91  
92     //---------------------------------
93     // Label the input
94     //---------------------------------
95     typename ConnectFilterType::Pointer inputConnectFilter=ConnectFilterType::New();
96     inputConnectFilter->SetInput(inputBinarizer->GetOutput());
97     inputConnectFilter->SetBackgroundValue(0);
98     inputConnectFilter->SetFullyConnected(m_FullyConnected);
99     if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
100     //   inputConnectFilter->Update();
101  
102     //---------------------------------
103     // Count the initial labels
104     //---------------------------------
105     typename StatisticsImageFilterType::Pointer inputStatisticsImageFilter=StatisticsImageFilterType::New();
106     inputStatisticsImageFilter->SetInput(inputConnectFilter->GetOutput());
107     if(m_Verbose) std::cout<<"Counting the initial labels..."<<std::endl;
108     inputStatisticsImageFilter->Update();
109     unsigned int initialNumberOfLabels= inputStatisticsImageFilter->GetMaximum();
110     if(m_Verbose) std::cout<<"The input contained "<<initialNumberOfLabels<<" disctictive label(s)..."<<std::endl;
111     if(m_Verbose) std::cout<<"Performing erosions till at least "<<initialNumberOfLabels+m_NumberOfNewLabels<<" distinctive labels are counted..."<<std::endl;
112  
113     //---------------------------------
114     // Structuring element
115     //---------------------------------
116     KernelType structuringElement;
117     structuringElement.SetRadius(m_Radius);
118     structuringElement.CreateStructuringElement();
119
120     //---------------------------------
121     // Repeat while not decomposed
122     //---------------------------------
123     typename InternalImageType::Pointer current=inputBinarizer->GetOutput();
124     typename InternalImageType::Pointer output=inputBinarizer->GetOutput();
125     unsigned int iteration=0;
126     unsigned int max =initialNumberOfLabels;
127
128     while (  (iteration < m_MinimumNumberOfIterations) || ( (max< initialNumberOfLabels + m_NumberOfNewLabels ) && (iteration<100 ) ) )
129       {
130
131
132         if(m_Verbose) std::cout<<"Eroding image (iteration "<<iteration<<")..."<<std::endl;
133         
134         //---------------------------------
135         // Erode
136         //---------------------------------
137         typename BinaryErodeImageFilterType::Pointer erosionFilter=BinaryErodeImageFilterType::New();
138         erosionFilter->SetInput (current);
139         erosionFilter->SetForegroundValue (1);
140         erosionFilter->SetBackgroundValue (-1);
141         erosionFilter->SetBoundaryToForeground(false);
142         erosionFilter->SetKernel(structuringElement);
143         erosionFilter->Update();
144         current=erosionFilter->GetOutput();
145         
146         //---------------------------------
147         // Binarize (remove -1)
148         //--------------------------------- 
149         typename  BinaryThresholdImageFilterType::Pointer binarizer=BinaryThresholdImageFilterType::New();
150         binarizer->SetInput(erosionFilter->GetOutput());
151         binarizer->SetLowerThreshold(1);
152         binarizer->SetUpperThreshold(1);
153         binarizer ->SetInsideValue(1);
154         binarizer ->SetOutsideValue(0);
155         if(m_Verbose) std::cout<<"Binarizing the eroded image..."<<std::endl;
156         //binarizer->Update();
157
158         
159         //---------------------------------
160         // ReLabel the connected components
161         //---------------------------------
162         typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
163         connectFilter->SetInput(binarizer->GetOutput());
164         connectFilter->SetBackgroundValue(0);
165         connectFilter->SetFullyConnected(m_FullyConnected);
166         if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
167         //connectFilter->Update();
168                 
169         //---------------------------------
170         // Sort
171         //---------------------------------
172         typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
173         relabelFilter->SetInput(connectFilter->GetOutput());
174         relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize);
175         //relabelFilter->Update();   
176         
177         
178         //---------------------------------
179         // Count the labels
180         //---------------------------------
181         typename StatisticsImageFilterType::Pointer statisticsImageFilter=StatisticsImageFilterType::New();
182         statisticsImageFilter->SetInput(relabelFilter->GetOutput());
183         statisticsImageFilter->Update();
184         max= statisticsImageFilter->GetMaximum();
185         if(m_Verbose) std::cout<<"Counted "<<max<<" label (s) larger then "<<m_MinimumObjectSize<<" voxels..."<<std::endl;
186         output=statisticsImageFilter->GetOutput();
187         
188         // Next iteration
189         iteration++;
190       }
191
192
193     //---------------------------------
194     // Binarize current (remove -1)
195     //--------------------------------- 
196     typename  BinaryThresholdImageFilterType::Pointer binarizer=BinaryThresholdImageFilterType::New();
197     binarizer->SetInput(current);
198     binarizer->SetLowerThreshold(1);
199     binarizer->SetUpperThreshold(1);
200     binarizer ->SetInsideValue(1);
201     binarizer ->SetOutsideValue(0);
202     if(m_Verbose) std::cout<<"Binarizing the eroded image..."<<std::endl;
203     //binarizer->Update();
204     
205     //---------------------------------
206     // ReLabel the connected components
207     //---------------------------------
208     typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
209     connectFilter->SetInput(binarizer->GetOutput());
210     connectFilter->SetBackgroundValue(0);
211     connectFilter->SetFullyConnected(m_FullyConnected);
212     if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
213     connectFilter->Update();
214     
215     //---------------------------------
216     // Sort
217     //---------------------------------
218     typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
219     relabelFilter->SetInput(connectFilter->GetOutput());
220     //relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize); // Preserve all intensities
221     //relabelFilter->Update();   
222
223     //---------------------------------
224     // Set -1 to padding value
225     //---------------------------------
226     typename SetBackgroundImageFilterType::Pointer setBackgroundFilter =SetBackgroundImageFilterType::New();
227     setBackgroundFilter->SetInput(relabelFilter->GetOutput());
228     setBackgroundFilter->SetInput2(current);
229     setBackgroundFilter->SetMaskValue(-1);
230     setBackgroundFilter->SetOutsideValue(m_ErosionPaddingValue);
231     if(m_Verbose) std::cout<<"Setting the eroded region to "<<m_ErosionPaddingValue<<"..."<<std::endl;
232         
233     //---------------------------------
234     // Cast
235     //---------------------------------
236     typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
237     typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
238     caster->SetInput(setBackgroundFilter->GetOutput());
239     caster->Update();
240     
241     //---------------------------------
242     // SetOutput
243     //---------------------------------
244     this->SetNthOutput(0, caster->GetOutput());
245   }
246
247
248 }//end clitk
249  
250 #endif //#define clitkDecomposeThroughErosionImageFilter_txx