1 #ifndef __clitkExplosionControlledThresholdConnectedImageFilter_txx
2 #define __clitkExplosionControlledThresholdConnectedImageFilter_txx
4 #include "clitkExplosionControlledThresholdConnectedImageFilter.h"
5 #include "itkBinaryThresholdImageFunction.h"
6 #include "itkFloodFilledImageFunctionConditionalIterator.h"
7 #include "itkShapedFloodFilledImageFunctionConditionalIterator.h"
8 #include "itkProgressReporter.h"
13 //--------------------------------------------------------------------
17 template <class TInputImage, class TOutputImage>
18 ExplosionControlledThresholdConnectedImageFilter<TInputImage, TOutputImage>
19 ::ExplosionControlledThresholdConnectedImageFilter()
21 m_Lower = itk::NumericTraits<InputImagePixelType>::NonpositiveMin();
22 m_Upper = itk::NumericTraits<InputImagePixelType>::max();
23 m_FinalLower = itk::NumericTraits<InputImagePixelType>::NonpositiveMin();
24 m_FinalUpper = itk::NumericTraits<InputImagePixelType>::max();
25 m_AdaptLowerBorder=false;
26 m_AdaptUpperBorder=false;
27 m_MaximumUpperThreshold=itk::NumericTraits<InputImagePixelType>::max();
28 m_MinimumLowerThreshold=itk::NumericTraits<InputImagePixelType>::NonpositiveMin();
30 m_ReplaceValue = itk::NumericTraits<OutputImagePixelType>::One;
31 m_MinimumThresholdStepSize=itk::NumericTraits<InputImagePixelType>::One;
32 m_ThresholdStepSize=64;
34 m_FullyConnected=false;
37 //--------------------------------------------------------------------
40 //--------------------------------------------------------------------
41 template <class TInputImage, class TOutputImage>
43 ExplosionControlledThresholdConnectedImageFilter<TInputImage, TOutputImage>
46 if( this->m_Seeds.size() > 0 )
48 this->m_Seeds.clear();
52 //--------------------------------------------------------------------
55 //--------------------------------------------------------------------
56 template <class TInputImage, class TOutputImage>
58 ExplosionControlledThresholdConnectedImageFilter<TInputImage, TOutputImage>
59 ::SetSeed(const IndexType & seed)
62 this->AddSeed ( seed );
64 //--------------------------------------------------------------------
67 //--------------------------------------------------------------------
68 template <class TInputImage, class TOutputImage>
70 ExplosionControlledThresholdConnectedImageFilter<TInputImage, TOutputImage>
71 ::AddSeed ( const IndexType & seed )
73 this->m_Seeds.push_back ( seed );
76 //--------------------------------------------------------------------
79 //--------------------------------------------------------------------
81 * Standard PrintSelf method.
83 template <class TInputImage, class TOutputImage>
85 ExplosionControlledThresholdConnectedImageFilter<TInputImage, TOutputImage>
86 ::PrintSelf(std::ostream& os, itk::Indent indent) const
88 this->Superclass::PrintSelf(os, indent);
89 os << indent << "Upper: "
90 << static_cast<typename itk::NumericTraits<InputImagePixelType>::PrintType>(m_Upper)
92 os << indent << "Lower: "
93 << static_cast<typename itk::NumericTraits<InputImagePixelType>::PrintType>(m_Lower)
95 os << indent << "ReplaceValue: "
96 << static_cast<double>(m_Multiplier)
98 os << indent << "ReplaceValue: "
99 << static_cast<typename itk::NumericTraits<OutputImagePixelType>::PrintType>(m_ReplaceValue)
102 //--------------------------------------------------------------------
105 //--------------------------------------------------------------------
106 template <class TInputImage, class TOutputImage>
108 ExplosionControlledThresholdConnectedImageFilter<TInputImage,TOutputImage>
109 ::GenerateInputRequestedRegion()
111 Superclass::GenerateInputRequestedRegion();
112 if ( this->GetInput() )
114 InputImagePointer image =
115 const_cast< InputImageType * >( this->GetInput() );
116 image->SetRequestedRegionToLargestPossibleRegion();
119 //--------------------------------------------------------------------
122 //--------------------------------------------------------------------
123 template <class TInputImage, class TOutputImage>
125 ExplosionControlledThresholdConnectedImageFilter<TInputImage,TOutputImage>
126 ::EnlargeOutputRequestedRegion(itk::DataObject *output)
128 Superclass::EnlargeOutputRequestedRegion(output);
129 output->SetRequestedRegionToLargestPossibleRegion();
131 //--------------------------------------------------------------------
134 //--------------------------------------------------------------------
135 template <class TInputImage, class TOutputImage>
137 ExplosionControlledThresholdConnectedImageFilter<TInputImage,TOutputImage>
140 typename Superclass::InputImageConstPointer inputImage = this->GetInput();
141 typename Superclass::OutputImagePointer outputImage = this->GetOutput();
144 outputImage->SetBufferedRegion( outputImage->GetRequestedRegion() );
145 outputImage->Allocate();
146 outputImage->FillBuffer ( itk::NumericTraits<OutputImagePixelType>::Zero );
149 //--------------------------------------------------
150 // Get initial region size
151 //--------------------------------------------------
152 typedef itk::BinaryThresholdImageFunction<InputImageType> FunctionType;
153 //typedef itk::ShapedFloodFilledImageFunctionConditionalIterator<OutputImageType, FunctionType> IteratorType;
154 typedef itk::FloodFilledImageFunctionConditionalIterator<OutputImageType, FunctionType> IteratorType;
155 typename FunctionType::Pointer function = FunctionType::New();
156 function->SetInputImage ( inputImage );
157 function->ThresholdBetween ( m_Lower, m_Upper );
158 IteratorType it = IteratorType ( outputImage, function, m_Seeds );
159 //it.SetFullyConnected(m_FullyConnected);
160 unsigned int initialSize=0;
163 while( !it.IsAtEnd())
168 if (m_Verbose) std::cout<<"Initial region size using thresholds ["<<m_Lower<<", "<<m_Upper<<"], is "<<initialSize<<"..."<<std::endl;
171 //--------------------------------------------------
172 // Decrease lower threshold
173 //--------------------------------------------------
174 m_FinalLower=m_Lower;
175 if (m_AdaptLowerBorder)
178 InputImagePixelType currentLower=m_Lower;
179 unsigned int currentSize=initialSize;
180 unsigned int previousSize=initialSize;
182 // Lower the threshold till explosion
183 while ( (previousSize<m_MinimumSize) || ( (currentLower> m_MinimumLowerThreshold) && ( (unsigned int) currentSize <= (unsigned int )m_Multiplier* previousSize) ) )
186 currentLower-=m_ThresholdStepSize;
187 function->ThresholdBetween(currentLower, m_Upper);
189 // Get current region size
190 previousSize=currentSize;
192 IteratorType it = IteratorType ( outputImage, function, m_Seeds );
194 while( !it.IsAtEnd())
199 if (m_Verbose) std::cout<<"Decreasing lower threshold to "<<currentLower<<", size is "<<currentSize <<"(previously "<<previousSize<<") ..."<<std::endl;
203 // Explosion occured, increase lower theshold
204 if ( (double)currentSize > m_Multiplier*(double) previousSize)
206 // Raise lower threshold
207 if (m_Verbose) std::cout<<"Explosion detected, adapting lower threshold ..."<<std::endl;
208 currentLower+=m_ThresholdStepSize;
209 InputImagePixelType currentStepSize=m_ThresholdStepSize;
211 while (currentStepSize>m_MinimumThresholdStepSize)
214 currentLower-=currentStepSize;
216 // Get current region size
218 IteratorType it = IteratorType ( outputImage, function, m_Seeds );
220 while( !it.IsAtEnd())
226 if (m_Verbose) std::cout<<"Adapting lower threshold to "<<currentLower<<", size is "<<currentSize <<"(previously "<<previousSize<<") ..."<<std::endl;
228 // Explosion: go back
229 if ((double)currentSize > m_Multiplier* (double) previousSize)
230 currentLower+=currentStepSize;
232 // No explosion: adapt previous
233 else previousSize=currentSize;
237 m_FinalLower=currentLower;
238 if (m_Verbose) std::cout<<"Final lower threshold (precision="<<m_MinimumThresholdStepSize<<") is set to "<<m_FinalLower<<"..."<<std::endl;
241 if (m_Verbose) std::cout<<"No explosion before minimum lower threshold reached!"<<std::endl;
244 } // end update lower
247 //--------------------------------------------------
248 // Increase upper threshold
249 //--------------------------------------------------
250 m_FinalUpper=m_Upper;
251 if (m_AdaptUpperBorder)
254 InputImagePixelType currentUpper=m_Upper;
255 unsigned int currentSize=initialSize;
256 unsigned int previousSize=initialSize;
258 // Upper the threshold till explosion
259 while ((previousSize<m_MinimumSize) || ( (currentUpper< m_MaximumUpperThreshold) && ((double)currentSize <= m_Multiplier* (double) previousSize) ) )
262 currentUpper+=m_ThresholdStepSize;
263 function->ThresholdBetween(m_Lower,currentUpper);
265 // Get current region size
266 previousSize=currentSize;
268 IteratorType it = IteratorType ( outputImage, function, m_Seeds );
270 while( !it.IsAtEnd())
275 if (m_Verbose) std::cout<<"Increasing upper threshold to "<<currentUpper<<", size is "<<currentSize <<"(previously "<<previousSize<<") ..."<<std::endl;
279 // Explosion occured, decrease upper theshold
280 if ((double)currentSize > m_Multiplier* (double) previousSize)
282 // Lower upper threshold
283 if (m_Verbose) std::cout<<"Explosion detected, adapting upper threshold ..."<<std::endl;
284 currentUpper-=m_ThresholdStepSize;
285 InputImagePixelType currentStepSize=m_ThresholdStepSize;
287 while (currentStepSize>m_MinimumThresholdStepSize)
290 currentUpper+=currentStepSize;
292 // Get current region size
294 function->ThresholdBetween(m_Lower,currentUpper);
295 IteratorType it = IteratorType ( outputImage, function, m_Seeds );
297 while( !it.IsAtEnd())
302 if (m_Verbose) std::cout<<"Adapting upper threshold to "<<currentUpper<<", size is "<<currentSize <<"(previously "<<previousSize<<") ..."<<std::endl;
304 // Explosion: go back
305 if ((double)currentSize > m_Multiplier* (double) previousSize)
306 currentUpper-=currentStepSize;
308 // No explosion: adapt previous
309 else previousSize=currentSize;
313 m_FinalUpper=currentUpper;
314 if (m_Verbose) std::cout<<"Final upper threshold (precision="<<m_MinimumThresholdStepSize<<") is set to "<<m_FinalUpper<<"..."<<std::endl;
317 else { if (m_Verbose) std::cout<<"No explosion before maximum upper threshold reached!"<<std::endl; }
319 } // end update upper
323 //--------------------------------------------------
324 // Update the output with final thresholds
325 //--------------------------------------------------
326 function->ThresholdBetween(m_FinalLower, m_FinalUpper);
327 IteratorType it2 = IteratorType ( outputImage, function, m_Seeds );
329 while( !it2.IsAtEnd())
331 it2.Set(m_ReplaceValue);
336 //--------------------------------------------------------------------
339 } // end namespace clitk