itk中的特征提取算法(五)
来源:互联网 发布:医疗器械公司软件开发 编辑:程序博客网 时间:2024/05/21 10:06
接上篇line识别,本文的内容是cirle识别。类名:itkHoughTransform2DCirclesImageFilter。
不废话,上用法代码:
typedef itk::HoughTransform2DCirclesImageFilter<unsigned char, float> HoughTransformFilterType;HoughTransformFilterType::Pointer hough = HoughTransformFilterType::New();hough->SetInput(input_data);hough->SetNumberOfCircles(1);hough->SetMinimumRadius(10);hough->SetMaximumRadius(300);hough->SetVariance(5);hough->SetSigmaGradient(1);hough->SetDiscRadiusRatio(2);hough->Update();功能:通过Hough变换找到2D图像中的圆
输入:灰度图像
输出:
1.存放圆心的累加器数组;
2.一个存放坐标的数组,带有半径属性。
源码分析:
1..h中的私有变量
private: HoughTransform2DCirclesImageFilter(const Self&); void operator=(const Self&); float m_SweepAngle; 扫描角度 0.0 double m_MinimumRadius; 最小半径 0 double m_MaximumRadius; 最大半径 10 double m_Threshold; 最小灰度下限 0 double m_SigmaGradient; 梯度参数 1 OutputImagePointer m_RadiusImage; CirclesListType m_CirclesList; unsigned int m_NumberOfCircles; float m_DiscRadiusRatio; 需要排除的半径 1 float m_Variance; 设置高斯模糊器的方差 10 unsigned long m_OldModifiedTime; 0 unsigned long m_OldNumberOfCircles; 02.数据生成
template<typename TInputPixelType, typename TOutputPixelType>voidHoughTransform2DCirclesImageFilter< TInputPixelType, TOutputPixelType>::GenerateData(){ // Get the input and output pointers InputImageConstPointer inputImage = this->GetInput(0); OutputImagePointer outputImage = this->GetOutput(0); // Allocate the output this->AllocateOutputs(); //输出图像涂黑 outputImage->FillBuffer(0); //高斯导数图像函数?梯度图?高斯模糊器? typedef GaussianDerivativeImageFunction<InputImageType> DoGFunctionType; typename DoGFunctionType::Pointer DoGFunction = DoGFunctionType::New(); DoGFunction->SetInputImage(inputImage); DoGFunction->SetSigma(m_SigmaGradient); //半径图像???NO,统计投票结果 m_RadiusImage = OutputImageType::New(); m_RadiusImage->SetRegions( outputImage->GetLargestPossibleRegion() ); m_RadiusImage->SetOrigin(inputImage->GetOrigin()); m_RadiusImage->SetSpacing(inputImage->GetSpacing()); m_RadiusImage->SetDirection(inputImage->GetDirection()); m_RadiusImage->Allocate(); m_RadiusImage->FillBuffer(0); //像素迭代器 ImageRegionConstIteratorWithIndex< InputImageType > image_it( inputImage, inputImage->GetRequestedRegion() ); image_it.Begin(); Index<2> index; Point<float,2> point; while( !image_it.IsAtEnd() )//逐点判断,一直迭代到最后一个点 { if(image_it.Get()>m_Threshold) { point[0] = image_it.GetIndex()[0]; point[1] = image_it.GetIndex()[1]; //获得该点的梯度 typename DoGFunctionType::VectorType grad = DoGFunction->EvaluateAtIndex(image_it.GetIndex()); double Vx = grad[0]; double Vy = grad[1]; if( (vcl_fabs(Vx)>1) || (vcl_fabs(Vy)>1) ) // if the gradient is not flat 梯度不够平坦 { double norm = vcl_sqrt(Vx*Vx+Vy*Vy); Vx /= norm; Vy /= norm; for(double angle = -m_SweepAngle;angle<=m_SweepAngle;angle+=0.05) { double i = m_MinimumRadius;//先将预设最小半径 double distance; do {//计算可能在圆上的点 index[0] = (long int)(point[0]-i*(Vx*vcl_cos(angle)+Vy*vcl_sin(angle))); index[1] = (long int)(point[1]-i*(Vx*vcl_sin(angle)+Vy*vcl_cos(angle))); //计算点与圆心的距离(疑似半径) distance = vcl_sqrt((index[1]-point[1])*(index[1]-point[1]) +(index[0]-point[0])*(index[0]-point[0]) ); if(outputImage->GetRequestedRegion().IsInside( index )) { outputImage->SetPixel(index, outputImage->GetPixel(index)+1); m_RadiusImage->SetPixel(index, (m_RadiusImage->GetPixel(index)+distance));//投票 } i=i+1;//半径每次+1 } while( outputImage->GetRequestedRegion().IsInside( index ) && (distance < m_MaximumRadius) ); } } } ++image_it; } // Compute the average radius ImageRegionConstIterator< OutputImageType > output_it( outputImage, outputImage->GetLargestPossibleRegion() ); ImageRegionIterator< OutputImageType > radius_it( m_RadiusImage, m_RadiusImage->GetLargestPossibleRegion() ); output_it.Begin(); radius_it.Begin(); while( !output_it.IsAtEnd() ) { if(output_it.Get()>0) { radius_it.Set(radius_it.Get()/output_it.Get()); } ++output_it; ++radius_it; }}原理:
已知圆的一般方程为:(x - a)^2 + (y - b)^2 = r^2
其中,(a, b)为圆心,r为圆的半径。
把X-Y平面上的圆转换到a-b-r参数空间,则图像空间中过(x, y)点圆对应参数空间中,高度r变化下的一个三维锥面,如下图:
这里摘抄一段网友的说法:
“ OpenCV内部提供了一个基于Hough变换理论的找圆算法,HoughCircle与一般的拟合圆算法比起来,各有优势:
优势:HoughCircle对噪声点不怎么敏感,并且可以在同一个图中找出多个圆;反观拟合圆算法,单纯的拟合结果容易受噪声点的影响,且不支持一个输入中找多个圆;
缺点:原始的Hough变换找圆,计算量很大,而且如果对查找圆的半径不加控制,不但运算量巨大,而且精度也不足,在输入噪声点不多的情况下,找圆效果远不如拟合找圆;为了提高找圆精度,相比拟合法,需要提供更多的参数加以控制,参数要求比较严格,且总体稳定性不佳;
OpenCV内的HoughCircles对基础的Hough变换找圆做了一定的优化来提高速度,它不再是在参数空间画出一个完整的圆来进行投票,而只是计算轮廓点处的梯度向量,然后根据搜索的半径R在该梯度方向距离轮廓点距离R的两边各投一点,最后根据投票结果图确定圆心位置。”
关键词:
投票
“佛说世间如梦如幻,一切都是刹那变化,我们执假为真,才不认识自己本来的面目。可大多数众生不知,就算知道了,还不是陷在其中不能自拔?”
---世间安得双全法,不负如来不负卿
1.http://www.opencv.org.cn/forum.php?mod=viewthread&tid=34096
2.https://itk.org/Doxygen/html/group__ImageFeatureExtraction.html
3.http://blog.csdn.net/lee_cv/article/details/9163001
4.《基于Hough 变换的圆检测方法》
阅读全文
0 0
- itk中的特征提取算法(五)
- itk中的特征提取算法(一)
- itk中的特征提取算法(二)
- itk中的特征提取算法(三)
- itk中的特征提取算法(四)
- itk中的图像分割算法(五)
- itk中的花式数据切割(五)
- ITK 基于特征的血管提取01
- ITK 基于特征的血管提取02
- itk中的图像分割算法(一)
- itk中的图像分割算法(二)
- itk中的图像分割算法(三)
- itk中的图像分割算法(四)
- 图像算法之五:特征提取算法之HOG
- itk中的数据细化算法
- itk中的黑白TopHat算法
- itk中的毛刺去除算法
- itk中的图像缩小算法
- UE4子弹到达目的地爆炸及自身销毁
- 对于一个"ul"列表,单击弹出每个"li"对应的索引
- f.反射
- 6月12日,每日20行。
- mysql---使用正则表达式搜索
- itk中的特征提取算法(五)
- java HashMap 与 Hashtable 详解
- ZONE_MOVABLE
- android CoordinatorLayout使用
- CRC校验
- vs中检测内存泄漏的方法
- hibernate 5.x创建SessionFactory
- 计算机专业导论其一
- Spring+redis 1、配置文件