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