栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Opencv 霍夫变换 霍夫圆检测

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Opencv 霍夫变换 霍夫圆检测

霍夫变换是一种特征提取术,在了解霍夫变换 霍夫检测之前 需要首先明白什么是霍夫空间:以圆形举例子,弄明白形状的原理,直线的变换与检测也就不难理解 霍夫空间,是一种三维空间,三个坐标分别为圆的横纵坐标,Z轴坐标为半径,所以霍夫圆变换的实质过程就是从二维空间的圆拓展到三维空间
霍夫圆检测:应用:识别红绿灯中信号灯(圆形)物体
在检测圆之前,需要做好边缘检测,这个步骤在Opencv的函数已经内置了,使用Canny算子进行边缘检测,参数需要自行调整
霍夫梯度法:
**检测原理简要概括:模向量 ,垂直于圆心,相交于一点,确定圆心
首先找到圆心 然后寻找半径
估计圆心步骤:
1.把原图做一次 Canny 边缘检测,得到边缘检测的二值图。
2.对原始图像执行一次 Sobel 算子,计算出所有像素的邻域梯度值。
3.初始化圆心空间 N(a,b),令所有的 N(a,b)=0。
4.遍历 Canny 边缘二值图中的所有非零像素点,沿着梯度方向 ( 切线的垂直方向 )画线,将线段经过的所有累加器中的点 (a,b) 的 N(a,b)+=1。 使用的累加器类似于C语言中的counter
5.每个点的counter大小和阈值做比较,如果大于该值,找到圆心,确定一个圆
确定圆心后,寻找半径:
估计半径(针对某一个圆心 (a,b))
1.计算 Canny 图中所有非 0 点距离圆心的距离。
2.距离从小到大排序,根据阈值,选取合适的可能半径(比如 3 和 3.5 都被划为半径值 3 中)。
3.初始化半径空间 r, N®=0。
4.遍历 Canny 图中的非 0 点,N( 距离 )+=1。
5.统计得到可能的半径值(N® 越大,说明这个距离值出现次数越多,越有可能是半径值)。

函数各个参数的意义:HoughCircle:
1:images 输入的图像
2:circles 输出的图像,圆的输出矢量
3.method,使用方法,默认为1,代表霍夫梯度下降
4.dp 分辨率,默认为1,两图分辨率相同
5.minDist 若两圆心距离小于该值 则认为两个圆属于同一个圆
6.para1,Canny算子的阈值
7.para2, 某点是否为圆心的判断阈值,直线相交阈值,大于该值,才能被认为筛选出来的一个圆
8.minradius 半径最小值 默认为0
9.maxradius 半径最大值 默认为0

代码实战:
原图:

调整代码之前:

调整参数以后:

准确率做到了一一对应,圆心的准确率一些图形吻合的比较好,一些还需要调参

开源代码:

// A code block
import cv2
import numpy as np
img = cv2.imread(r"C:UsersWM202Picturescircle.jpg")
GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
GrayImage= cv2.medianBlur(GrayImage,5)
ret,th1 = cv2.threshold(GrayImage,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(GrayImage,255,cv2.ADAPTIVE_THRESH_MEAN_C,  
                    cv2.THRESH_BINARY,3,5)  
th3 = cv2.adaptiveThreshold(GrayImage,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,  
                    cv2.THRESH_BINARY,3,5)


kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(th2,kernel,iterations=1)
dilation = cv2.dilate(erosion,kernel,iterations=1)

imgray=cv2.Canny(erosion,30,100)

circles = cv2.HoughCircles(imgray,cv2.HOUGH_GRADIENT,1,40,
                            param1=50,param2=10,minRadius=10,maxRadius=80)

circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    # draw the outer circle
    cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2)
    # draw the center of the circle
    cv2.circle(img,(i[0],i[1]),2,(0,0,255),3)
print(len(circles[0,:]))

cv2.namedWindow("detected circles",cv2.WINDOW_NORMAL )
cv2.imshow('detected circles',img)

cv2.waitKey(0)
cv2.destroyAllWindows()

如果你在学习这一部分的时候 或者在调试代码的时候有遇到任何的问题,欢迎留言评论!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/994896.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号