【OpenCV + Python】Hough 圆环变换
• 学习使用霍夫变换在图像中找圆形(环)。
• 学习函数:cv2.HoughCircles()。
首先对图像进行canny边缘检测,对边缘中的每一个非0点,通过Sobel算法计算局部梯度。那么计算得到的梯度方向,实际上就是圆切线的法线。三条法线即可确定一个圆心,同理在累加器中对圆心通过的法线进行累加,就得到了圆环的判定。
cv2.HoughCircles(image, method, dp, minDist, circles, param1, param2, minRadius, maxRadius)
image为输入图像,需要灰度图
method为检测方法,常用CV_HOUGH_GRADIENT
dp为检测内侧圆心的累加器图像的分辨率于输入图像之比的倒数,如dp=1,累加器和输入图像具有相同的分辨率,如果dp=2,累计器便有输入图像一半那么大的宽度和高度
minDist表示两个圆之间圆心的最小距离
param1有默认值100,它是method设置的检测方法的对应的参数,对当前唯一的方法霍夫梯度法cv2.HOUGH_GRADIENT,它表示传递给canny边缘检测算子的高阈值,而低阈值为高阈值的一半
param2有默认值100,它是method设置的检测方法的对应的参数,对当前唯一的方法霍夫梯度法cv2.HOUGH_GRADIENT,它表示在检测阶段圆心的累加器阈值,它越小,就越可以检测到更多根本不存在的圆,而它越大的话,能通过检测的圆就更加接近完美的圆形了
minRadius有默认值0,圆半径的最小值
maxRadius有默认值0,圆半径的最大值
实例:
import cv2
import numpy as np
img = cv2.imread('opencv.jpg',1)
img = cv2.medianBlur(img,7)
result = img.copy()
cimg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
circles = cv2.HoughCircles(cimg,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=80,maxRadius=120)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:# draw the outer circlecv2.circle(result,(i[0],i[1]),i[2],(255,255,0),2)# draw the center of the circlecv2.circle(result,(i[0],i[1]),2,(0,0,255),3)
cv2.imshow('img', img)
cv2.imshow('result',result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Hough变换不仅适用于直线检测,还适用于任何形式的f(x,a)=0所表示的图形的检测,其中x 表示坐标向量,a表示系数向量。下边我们对Hough变换检测圆的原理做简要介绍。
对于一个半径为r,圆心为(a,b)的圆,我们将其表示为:
此时x=[x,y]T,a=[a,b,r]T,其参数空间为三维。
显然,图像空间上的一点(x,y),在参数空间中对应着一个圆锥,如下图所示。
而图像空间的一个圆就对应着这一簇圆锥相交的一个点,这个特定点在参数空间的三维参数一定,就表示一定半径一定圆心坐标的图像空间的那个圆。
上述方法是经典的Hough圆检测方法的原理,它具有精度高,抗干扰能力强等优点,但由于该方法的参数空间为三维,要在三维空间上进行证据累计的话,需要的时间和空间都是庞大的,在实际应用中不适用。
为加快Hough变换检测圆的速度,学者们进行了大量研究,也出现了很多改进的Hough变换检测圆的方法。
如利用图像梯度信息的Hough变换,对圆的标准方程对x求导得到下式:
从上式看出,此时的参数空间从半径r,圆心(a,b)三维,变成了只有圆心(a,b)的二维空间,利用这种方法检测圆其计算量明显减少了。
但这种改进的Hough变换检测圆的方法其检测精度并不高,原因在于,此种方法利用了边界斜率。
从本质上讲,边界斜率其实是用曲线在某一点的弦的斜率来代替的,这种情况下,要保证不存在误差,只有在弦长为零的情况。
但在数字图像中,曲线的表现形式是离散的,其在某一点处的斜率指的是此点右向n步斜率或是左向n步斜率。
如果弦长过小了,斜率的量化误差就会增大。
这种方法比较适用于干扰较少的完整圆形目标。
除了上述方法外,还有其他的一些Hough圆检测算法。
如随机Hough变换,它的主要思想是通过在图像空间中随机抽样来降低内存需求与计算时间,具体做法是在图像空间中随机选取不共线的三点映射到参数空间,参数空间的单元集是一个动态链表结构,当参数单元陈列的值到达一定阈值就认为其确定了一个圆,将其作为候选圆,再通告证据累计统计图像空间中落在该候选圆上的点数,若点数大于一定阈值,确认为真实圆。
此种方法有效的降低了计算量和时间消耗,但其也存在一定问题,如无效累积量大,检测效率不高等,其检测精度也低于经典的Hough变换。
另外还有王建峰等改进的快速随机Hough变换,其基本思想是,考虑到圆必定在其外接正方形之内,为了减少随机Hough变换的无效累计,可以只对外接正方形之内的像素进行计算,之外的像素可以直接排除,这样大大降低了计算时间。
可以取边缘厚度为一个较小数t,对于任意三点确定对应的参数圆心(a,b)和半径r,边缘点集中的点di(dix,diy),如果有dix >a+r+t或dix <a-r-t或diy >b+r+t或diy <b-r-t,则不必对其进行计算。
通过这种方法就可以排除大量不是候选圆的点,提高了速度。
这种方法的缺点是没有解决好候选圆外接或者内切正方形的边长问题。
通常情况下,影响常规Hough变换的运算速度的因素主要有:参数空间的维数,边缘点的数量,运算的复杂性,参数空间的离散化程度,以及最后的峰值检测等。
最后原理转载地址:https://blog.csdn.net/jiangsgyx/article/details/83755739
应用:
计算圆的个数,定位等。
【OpenCV + Python】Hough 圆环变换相关推荐
- 【OpenCV-Python】教程:3-13 Hough直线变换
OpenCV Python Hough直线变换 [目标] 理解Hough变换的概念 学会使用Hough变换检测直线 cv2.HoughLines(), cv2.HoughLinesP() [理论] H ...
- Python OpenCV -- 霍夫线变换(十二)
霍夫线变换 1. 霍夫线变换是一种用来寻找直线的方法. 2. 是用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像. 实现: 1. 一条直线在图像二维空间 ...
- 使用Python,OpenCV和Hough圆检测图像中的圆
使用Python,OpenCV和Hough圆检测图像中的圆 1. 效果图 2. cv2.HoughCircles(image, method, dp, minDist) 3. 源码 参考 前几篇博客中 ...
- OpenCV 霍夫线变换Hough Line Transform
OpenCV 霍夫线变换Hough Line Transform 霍夫线变换Hough Line Transform 目标 理论 霍夫线变换 它是如何工作的? 标准概率霍夫线变换 这个程序做什么? 代 ...
- python离散余弦变换_在python3下使用OpenCV做离散余弦变换DCT及其反变换IDCT
对图像处理经常用到DCT, Python下有很多带有DCT算法包, 这里使用OpenCV的DCT做变换, 并简单置0部分数据, 再查看反变换图像的效果. import numpy as np impo ...
- Python+OpenCV:Hough圆检测(Hough Circle Transform)
Python+OpenCV:Hough圆检测(Hough Circle Transform) ##################################################### ...
- Python+OpenCV:Hough直线检测(Hough Line Transform)
Python+OpenCV:Hough直线检测(Hough Line Transform) 理论 A line can be represented as or in a parametric fo ...
- python直角坐标转极坐标_Python在OpenCV里实现极坐标变换功能
在中学里学习过直角坐标系,也叫做笛卡尔坐标系,它是正交坐标系,不过也学习过极坐标系,这种坐标系比较适合大炮发射的场合.极坐标系的定义如下: 在 平面内取一个定点O, 叫极点,引一条射线Ox,叫做极轴, ...
- Hough直线变换、圆变换原理解析与python实验
霍夫变换 在图像x-y坐标中,经过点(x_i, y_i)的直线表示为y_i=k∗ x_i+b (1),其中k为斜率,b为截距 如果将x_i .y_i 看成常数,把k和b看成变量,式子(1)可以表示为b ...
最新文章
- SQL 进阶技巧(上)
- Windows查看网络端口被占用情况netstat命令
- 【 Grey Hack 】万金油脚本:在路由器上获取shell
- HttpClient通过Post方式发送Json数据
- 深搜+广搜——Lake Counting S(洛谷 P1596)
- android 加载更多动画效果,Android实践之带加载效果的下拉刷新上拉加载更多
- hexo搭建个人博客_hexo 搭建个人博客
- 如何在 Django REST Framework 中对分页结果过滤和排序?
- 移动web适配利器-rem
- html的选择字体样式代码,html 常用字体(示例代码)
- 数学建模之蒙特卡罗模型
- 大数据未来7大发展趋势
- Python爬虫爬取微博评论案例详解
- 双色球彩票核心算法(java)
- JVM之枚举GC Roots 根节点,安全点,安全区域。
- 基于Visual Question Answerin的视觉图像文本图像处理系统 设计报告+Python设计源码
- 硬件架构“变天”了,不能只见树木不见森林
- 关于封包工具一上午的研究总结
- MemTest内存软件测试介绍说明-2
- 魔乐科技安卓开发教程----李兴华----13视频录制
热门文章
- LOG高斯-拉普拉斯算子
- CF115B Lawnmower(贪心)
- C: Warning: implicit declaration of function ‘e‘; did you mean ‘el‘?[-Wimplicit-function-declaration
- Spring详细教程入门(一)
- java计算机毕业设计ssm党支部在线学习系统
- 手机广告 开源SNS
- 解决安装文件时2502、2503错误
- 你们要的Java学习路线图,来喽
- Java学习路线图分享(含项目+面试提升)最全整理
- 主题模型LDA、NMF、LSA