1 #ifndef clitkDecomposeThroughErosionImageFilter_txx
2 #define clitkDecomposeThroughErosionImageFilter_txx
4 /* =================================================
5 * @file clitkDecomposeThroughErosionImageFilter.txx
11 ===================================================*/
17 //-------------------------------------------------------------------
18 // Update with the number of dimensions
19 //-------------------------------------------------------------------
20 template<class InputImageType, class OutputImageType>
21 DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::DecomposeThroughErosionImageFilter()
28 m_ErosionPaddingValue=static_cast<OutputPixelType>(-1);
29 for (unsigned int i=0; i<InputImageDimension; i++)
31 m_NumberOfNewLabels=1;
32 m_FullyConnected=true;
33 m_MinimumObjectSize=10;
34 m_MinimumNumberOfIterations=1;
38 //-------------------------------------------------------------------
39 // Update with the number of dimensions and the pixeltype
40 //-------------------------------------------------------------------
41 template<class InputImageType, class OutputImageType>
43 DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::GenerateData()
46 //---------------------------------
48 //---------------------------------
51 typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
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;
63 //---------------------------------
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();
75 //---------------------------------
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();
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;
96 //---------------------------------
97 // Structuring element
98 //---------------------------------
99 KernelType structuringElement;
100 structuringElement.SetRadius(m_Radius);
101 structuringElement.CreateStructuringElement();
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;
111 while ( (iteration < m_MinimumNumberOfIterations) || ( (max< initialNumberOfLabels + m_NumberOfNewLabels ) && (iteration<100 ) ) )
115 if(m_Verbose) std::cout<<"Eroding image (iteration "<<iteration<<")..."<<std::endl;
117 //---------------------------------
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();
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();
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();
152 //---------------------------------
154 //---------------------------------
155 typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
156 relabelFilter->SetInput(connectFilter->GetOutput());
157 relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize);
158 //relabelFilter->Update();
161 //---------------------------------
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();
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();
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();
198 //---------------------------------
200 //---------------------------------
201 typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
202 relabelFilter->SetInput(connectFilter->GetOutput());
203 //relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize); // Preserve all intensities
204 //relabelFilter->Update();
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;
216 //---------------------------------
218 //---------------------------------
219 typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
220 typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
221 caster->SetInput(setBackgroundFilter->GetOutput());
224 //---------------------------------
226 //---------------------------------
227 this->SetNthOutput(0, caster->GetOutput());
233 #endif //#define clitkDecomposeThroughErosionImageFilter_txx