18 #ifndef __itkHoughTransform2DCirclesImageFilter_txx
19 #define __itkHoughTransform2DCirclesImageFilter_txx
31 template<
typename TInputPixelType,
typename TOutputPixelType>
39 m_DiscRadiusRatio = 1;
41 m_OldModifiedTime = 0;
42 m_OldNumberOfCircles = 0;
44 m_NumberOfCircles = 1;
47 template<
typename TInputPixelType,
typename TOutputPixelType>
52 this->SetMinimumRadius(radius);
53 this->SetMaximumRadius(radius);
56 template<
typename TInputPixelType,
typename TOutputPixelType>
61 Superclass::EnlargeOutputRequestedRegion(output);
66 template<
typename TInputPixelType,
typename TOutputPixelType>
71 Superclass::GenerateInputRequestedRegion();
72 if ( this->GetInput() )
76 image->SetRequestedRegionToLargestPossibleRegion();
80 template<
typename TInputPixelType,
typename TOutputPixelType>
91 this->AllocateOutputs();
92 outputImage->FillBuffer(0);
95 typename DoGFunctionType::Pointer DoGFunction = DoGFunctionType::New();
96 DoGFunction->SetInputImage(inputImage);
97 DoGFunction->SetSigma(m_SigmaGradient);
99 m_RadiusImage = OutputImageType::New();
101 m_RadiusImage->SetRegions( outputImage->GetLargestPossibleRegion() );
102 m_RadiusImage->SetOrigin(inputImage->GetOrigin());
103 m_RadiusImage->SetSpacing(inputImage->GetSpacing());
104 m_RadiusImage->SetDirection(inputImage->GetDirection());
105 m_RadiusImage->Allocate();
106 m_RadiusImage->FillBuffer(0);
114 while( !image_it.IsAtEnd() )
116 if(image_it.Get()>m_Threshold)
118 point[0] = image_it.GetIndex()[0];
119 point[1] = image_it.GetIndex()[1];
125 if( (vcl_fabs(Vx)>1) || (vcl_fabs(Vy)>1) )
127 double norm = vcl_sqrt(Vx*Vx+Vy*Vy);
131 for(
double angle = -m_SweepAngle;angle<=m_SweepAngle;angle+=0.05)
133 double i = m_MinimumRadius;
138 index[0] = (
long int)(point[0]-i*(Vx*vcl_cos(angle)+Vy*vcl_sin(angle)));
139 index[1] = (
long int)(point[1]-i*(Vx*vcl_sin(angle)+Vy*vcl_cos(angle)));
141 distance = vcl_sqrt((index[1]-point[1])*(index[1]-point[1])
142 +(index[0]-point[0])*(index[0]-point[0]) );
145 if(outputImage->GetRequestedRegion().IsInside( index ))
147 outputImage->SetPixel(index, outputImage->GetPixel(index)+1);
148 m_RadiusImage->SetPixel(index, (m_RadiusImage->GetPixel(index)+distance));
153 }
while( outputImage->GetRequestedRegion().IsInside( index )
154 && (distance < m_MaximumRadius) );
166 while( !output_it.IsAtEnd() )
168 if(output_it.Get()>0)
170 radius_it.Set(radius_it.Get()/output_it.Get());
179 template<
typename TInputPixelType,
typename TOutputPixelType>
184 if((this->GetMTime() == m_OldModifiedTime) && (n == m_OldNumberOfCircles))
186 return m_CirclesList;
189 m_CirclesList.clear();
195 outputImage->SetRegions( this->GetOutput(0)->GetLargestPossibleRegion() );
196 outputImage->SetOrigin(this->GetOutput(0)->GetOrigin());
197 outputImage->SetSpacing(this->GetOutput(0)->GetSpacing());
198 outputImage->SetDirection(this->GetOutput(0)->GetDirection());
199 outputImage->Allocate();
200 outputImage->FillBuffer(0);
216 typename GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
218 gaussianFilter->SetInput(outputImage);
220 variance[0] = m_Variance;
221 variance[1] = m_Variance;
222 gaussianFilter->SetVariance(variance);
223 gaussianFilter->Update();
224 typename InternalImageType::Pointer postProcessImage = gaussianFilter->GetOutput();
227 typename MinMaxCalculatorType::Pointer minMaxCalculator = MinMaxCalculatorType::New();
232 unsigned int circles=0;
235 const double nPI = 4.0 * vcl_atan( 1.0 );
240 minMaxCalculator->SetImage(postProcessImage);
241 minMaxCalculator->ComputeMaximum();
242 InternalImageType::PixelType max = minMaxCalculator->GetMaximum();
245 for(it_input.GoToBegin();!it_input.IsAtEnd();++it_input)
247 if(it_input.Get() == max)
251 Circle->SetId(circles);
252 Circle->SetRadius(m_RadiusImage->GetPixel(it_input.GetIndex()));
255 center[0] = it_input.GetIndex()[0];
256 center[1] = it_input.GetIndex()[1];
257 Circle->GetObjectToParentTransform()->SetOffset(center);
258 Circle->ComputeBoundingBox();
260 m_CirclesList.push_back(Circle);
263 for(
double angle = 0; angle <= 2*nPI; angle += nPI/1000)
265 for(
double length = 0; length < m_DiscRadiusRatio*Circle->GetRadius()[0];length += 1)
267 index[0] = (
long int)(it_input.GetIndex()[0] + length * vcl_cos(angle));
268 index[1] = (
long int)(it_input.GetIndex()[1] + length * vcl_sin(angle));
269 if(postProcessImage->GetLargestPossibleRegion().IsInside( index ))
271 postProcessImage->SetPixel(index,0);
275 minMaxCalculator->SetImage(postProcessImage);
276 minMaxCalculator->ComputeMaximum();
277 max = minMaxCalculator->GetMaximum();
281 if(circles == m_NumberOfCircles)
break;
284 }
while((circles<m_NumberOfCircles) && (found));
286 m_OldModifiedTime = this->GetMTime();
287 m_OldNumberOfCircles = m_CirclesList.size();
288 return m_CirclesList;
293 template<
typename TInputPixelType,
typename TOutputPixelType>
298 Superclass::PrintSelf(os,indent);
300 os <<
"Threshold: " << m_Threshold << std::endl;
301 os <<
"Minimum Radius: " << m_MinimumRadius << std::endl;
302 os <<
"Maximum Radius: " << m_MaximumRadius << std::endl;
303 os <<
"Derivative Scale : " << m_SigmaGradient << std::endl;
304 os <<
"Radius Image Information : " << m_RadiusImage << std::endl;
305 os <<
"Number Of Circles: " << m_NumberOfCircles << std::endl;
306 os <<
"Disc Radius: " << m_DiscRadiusRatio << std::endl;
307 os <<
"Accumulator blur variance: " << m_Variance << std::endl;
308 os <<
"Sweep angle : " << m_SweepAngle << std::endl;