图形可以用一些参数进行表示,标准霍夫变换的原理就是把图像空间转换成参数空间(即霍夫空间),例如霍夫变换的直线检测就是在距离-角度空间内进行检测。圆可以表示成:

(x-a)2+(y-b)2=r2                   (1)

其中a和b表示圆心坐标,r表示圆半径,因此霍夫变换的圆检测就是在这三个参数组成的三维空间内进行检测。

原则上,霍夫变换可以检测任何形状。但复杂的形状需要的参数就多,霍夫空间的维数就多,因此在程序实现上所需的内存空间以及运行效率上都不利于把标准霍夫变换应用于实际复杂图形的检测中。所以一些改进的霍夫变换就相继提出,它们的基本原理就是尽可能减小霍夫空间的维数。

HoughCircles函数实现了圆形检测,它使用的算法也是改进的霍夫变换——2-1霍夫变换(21HT)。也就是把霍夫变换分为两个阶段,从而减小了霍夫空间的维数。第一阶段用于检测圆心,第二阶段从圆心推导出圆半径。检测圆心的原理是圆心是它所在圆周所有法线的交汇处,因此只要找到这个交点,即可确定圆心,该方法所用的霍夫空间与图像空间的性质相同,因此它仅仅是二维空间。检测圆半径的方法是从圆心到圆周上的任意一点的距离(即半径)是相同,只要确定一个阈值,只要相同距离的数量大于该阈值,我们就认为该距离就是该圆心所对应的圆半径,该方法只需要计算半径直方图,不使用霍夫空间。圆心和圆半径都得到了,那么通过公式1一个圆形就得到了。从上面的分析可以看出,2-1霍夫变换把标准霍夫变换的三维霍夫空间缩小为二维霍夫空间,因此无论在内存的使用上还是在运行效率上,2-1霍夫变换都远远优于标准霍夫变换。但该算法有一个不足之处就是由于圆半径的检测完全取决于圆心的检测,因此如果圆心检测出现偏差,那么圆半径的检测肯定也是错误的。2-1霍夫变换的具体步骤为:

第一阶段:检测圆心

1.1、对输入图像边缘检测;

1.2、计算图形的梯度,并确定圆周线,其中圆周的梯度就是它的法线;

1.3、在二维霍夫空间内,绘出所有图形的梯度直线,某坐标点上累加和的值越大,说明在该点上直线相交的次数越多,也就是越有可能是圆心;

1.4、在霍夫空间的4邻域内进行非最大值抑制;

1.5、设定一个阈值,霍夫空间内累加和大于该阈值的点就对应于圆心。

第二阶段:检测圆半径

2.1、计算某一个圆心到所有圆周线的距离,这些距离中就有该圆心所对应的圆的半径的值,这些半径值当然是相等的,并且这些圆半径的数量要远远大于其他距离值相等的数量;

2.2、设定两个阈值,定义为最大半径和最小半径,保留距离在这两个半径之间的值,这意味着我们检测的圆不能太大,也不能太小;

2.3、对保留下来的距离进行排序;

2.4、找到距离相同的那些值,并计算相同值的数量;

2.5、设定一个阈值,只有相同值的数量大于该阈值,才认为该值是该圆心对应的圆半径;

2.6、对每一个圆心,完成上面的2.1~2.5步骤,得到所有的圆半径。

HoughCircles函数的原型为:

void HoughCircles(InputArray image,OutputArray circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0,int maxRadius=0 )

image为输入图像,要求是灰度图像

circles为输出圆向量,每个向量包括三个浮点型的元素——圆心横坐标,圆心纵坐标和圆半径

method为使用霍夫变换圆检测的算法,Opencv2.4.9只实现了2-1霍夫变换,它的参数是CV_HOUGH_GRADIENT

dp为第一阶段所使用的霍夫空间的分辨率,dp=1时表示霍夫空间与输入图像空间的大小一致,dp=2时霍夫空间是输入图像空间的一半,以此类推

minDist为圆心之间的最小距离,如果检测到的两个圆心之间距离小于该值,则认为它们是同一个圆心

param1为边缘检测时使用Canny算子的高阈值

param2为步骤1.5和步骤2.5中所共有的阈值

minRadius和maxRadius为所检测到的圆半径的最小值和最大值

HoughCircles函数在sources/modules/imgproc/src/hough.cpp文件内被定义:

void cv::HoughCircles( InputArray _image, OutputArray _circles,int method, double dp, double min_dist,double param1, double param2,int minRadius, int maxRadius )
{//定义一段内存Ptr<CvMemStorage> storage = cvCreateMemStorage(STORAGE_SIZE);Mat image = _image.getMat();    //提取输入图像矩阵CvMat c_image = image;    //矩阵转换//调用cvHoughCircles函数CvSeq* seq = cvHoughCircles( &c_image, storage, method,dp, min_dist, param1, param2, minRadius, maxRadius );//把序列转换为矩阵seqToMat(seq, _circles);
}

cvHoughCircles函数为:

CV_IMPL CvSeq*
cvHoughCircles( CvArr* src_image, void* circle_storage,int method, double dp, double min_dist,double param1, double param2,int min_radius, int max_radius )
{CvSeq* result = 0;CvMat stub, *img = (CvMat*)src_image;CvMat* mat = 0;CvSeq* circles = 0

Opencv2.4.9源码分析——HoughCircles相关推荐

  1. Opencv2.4.9源码分析要点摘录

    以下摘录自 http://blog.csdn.net/zhaocj?viewmode=contents Opencv2.4.9源码分析要点摘录 Boosting AdaBoost的计算步骤: 1.设有 ...

  2. Opencv2.4.9源码分析——SURF

     SURF (Speeded Up Robust Features)是一种具有鲁棒性的局部特征检测算法,它首先由Herbert Bay等人于2006年提出,并在2008年进行了完善.其实该算法是H ...

  3. OpenCV2.4.9源码分析——Support Vector Machines

    引言 本文共分为三个部分,第一个部分介绍SVM的原理,我们全面介绍了5中常用的SVM算法:C-SVC.ν-SVC.单类SVM.ε-SVR和ν-SVR,其中C-SVC和ν-SVC不仅介绍了处理两类分类问 ...

  4. Opencv2.4.9源码分析——Stitching(四)

    4.图像投影变换 4.1 原理 前文我们已经说过,每幅图像是相机在不同角度下拍摄得到的,它们并不在同一个投影平面上,如果对重叠部分直接进行拼接,则会破坏实际场景的视觉一致性.所以我们需要在拼接之前,对 ...

  5. Opencv2.4.9源码分析——Stitching(二)

    2.计算单应矩阵 2.1 原理 在得到了图像特征点以后,我们就可以根据这些特征点,实现图像匹配,即得到重叠区域.而要把多幅图像拼接成一幅图像,就需要以某幅图像为基准,把其他图像映射到该图像所在的平面. ...

  6. Opencv2.4.9源码分析——Stitching(五)

    5.曝光补偿 5.1 原理 即使通过几何投影,图像之间可以做到很好的拼接,但如果不同图像之间有不同的曝光程度,那么拼接图像中的重叠部分也会出现明显的边缘,这样就使图像看起来十分不自然.因此,我们还需要 ...

  7. Opencv2.4.9源码分析——Stitching(一)

    相机镜头所呈现出的景物要比人类的视觉系统所看到的景物要狭小得多,因此一幅图像不可能捕获到我们所看到的整个景物.全景图像拼接给出了这个问题的解决办法,它是把图像间重叠部分拿出来拼接起来,从而得到一幅更大 ...

  8. Opencv2.4.9源码分析——HoughLinesP

    http://blog.csdn.net/zhaocj/article/details/400473 标准霍夫变换本质上是把图像映射到它的参数空间上,它需要计算所有的M个边缘点,这样它的运算量和所需内 ...

  9. SVM算法及OpenCV源码分析

    关于SVM原理,请参看: 系统学习机器学习之SVM(一) 系统学习机器学习之SVM(二) 系统学习机器学习之SVM(三)--Liblinear,LibSVM使用整理,总结 系统学习机器学习之SVM(四 ...

最新文章

  1. tf.keras.layers.MaxPool2D 最大池化层 示例
  2. 特斯拉撞了警车:Autopilot全程开启,连撞两车还没自动停下
  3. 愿...统一沟通...易行天下!
  4. socket.io 之 engine.io
  5. 【机器学习】粗糙集属性约简算法与mRMR算法的本质区别
  6. Android:IntentService的学习
  7. java-pdf转word,java开发面试笔试题
  8. php mosquitto,mosquitto 扩展安装php客户端库-Go语言中文社区
  9. 关于sql中字符串的疑惑
  10. 计算机专业必须考过英语4级吗,计算机专业英语必须过六级吗
  11. ios描述文件安装的问题
  12. python 获取网页元素_Python爬虫--解析网页中的元素
  13. 仓库盘点好方法,使用安卓盘点机PDA扫描商品条码进行超市盘点
  14. signature=5a537e48de3abe15561f136edabc54dc,Visual Signatures in Video Visualization
  15. 垃圾分类小程序,包含垃圾图片识别,答题,添加垃圾,搜索垃圾,科普视频等功能
  16. 开源项目——寝室助手
  17. springboot整合redis报错org.springframework.beans.factory.UnsatisfiedDependencyException
  18. GT30L32S4W中文字库芯片+墨水屏显示调好程序分享
  19. 【计算思维题】少儿编程 蓝桥杯青少组计算思维题真题及解析第1套
  20. 大厂面试突击——集合篇

热门文章

  1. Qt学习:QMessageBox(消息对话框)
  2. 利用伪元素给图片在鼠标悬停时添加背景图片
  3. Augularjs学习思维导图
  4. 毛驴也能网上买,农村淘宝想象空间到底有多大?
  5. 正则化(regularization)方法总结
  6. HZOJ 辣鸡(ljh)
  7. nfs-ganesha使用
  8. 东北大学计算机衰落,东北985大学“F4”现状:哈工大如日中天,吉大、东北大学没落!...
  9. 全国最大的民营航空公司告诉你,如何做好企业微信运营?
  10. 时间复杂度的五个记号