HoughCircle函数能够在一个图片上找到多个圆,十分容易使用,并且HoughCircle对噪声点不怎么敏感。OpenCV内的HoughCircles对基础的Hough变换找圆做了一定的优化来提高速度,它不再是在参数空间画出一个完整的圆来进行投票,而只是计算轮廓点处的梯度向量,然后根据搜索的半径r在该梯度方向距离轮廓点距离r的两边各投一点,最后根据投票结果图确定圆心位置。
HoughCircle函数在opencv4.5.2的定义:
def HoughCircles(image, method, dp, minDist, circles=..., param1=..., param2=..., minRadius=..., maxRadius=...) -> typing.Any:
不过一般情况下我们都是这样使用:
circle = cv2.HoughCircles(temp,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=10,minRadius=0,maxRadius=800)
注意:在数据之前必须要加入“参数=”,不然会出现各种错误,不是无返回值就是直接报错
参数解释:
image:为输入图像,要求必须是灰度图像;
method:为使用霍夫变换圆检测的算法,Opencv只实现了2-1霍夫变换,它的参数是CV_HOUGH_GRADIENT;(一直都是如此)
dp:为第一阶段所使用的霍夫空间的分辨率,dp=1时表示霍夫空间与输入图像空间的大小 一致,dp=2时霍夫空间是输入图像空间的一半,以此类推;
minDist:为圆心之间的最小距离,如果检测到的两个圆心之间距离小于该值,则认为它们是同一个圆心;
circles:为输出圆向量,每个向量包括三个浮点型的元素——圆心横坐标,圆心纵坐标和圆半径(三维数组);
注意:a , b, c = circle.shape(圆存在)(shape返回数组维数的个数的参数)
参数a代表着二维数组的个数,参数b代表着圆的数量,参数c代表着半径.
param1:有默认值100,它是method设置的检测方法的对应的参数,对当前唯一的方法霍夫梯度法cv2.HOUGH_GRADIENT,它表示传递给canny边缘检测算子的高阈值,而低阈值为高阈值的一半
param2:有默认值100,它是method设置的检测方法的对应的参数,对当前唯一的方法霍夫梯度法cv2.HOUGH_GRADIENT,它表示在检测阶段圆心的累加器阈值,它越小,就越可以检测到更多根本不存在的圆,而它越大的话,能通过检测的圆就更加接近完美的圆形了。
minRadius:有默认值0,圆半径的最小值
maxRadius:有默认值0,圆半径的最大值
我在一张图上画出圆的圆心和圆周,因此要用到circle函数,代码如下:
import numpy as np
import cv2 as cv
src = cv.imread('D:\pythonQt\openCV\\blackcircle.jpg', cv.IMREAD_COLOR)
img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
img = cv.medianBlur(img, 5) #起到一定的过滤作用
cimg = src.copy()
# circles = cv.HoughCircles(img,cv.HOUGH_GRADIENT,1,20,param1=500,param2=100,minRadius=30,maxRadius=800) #返回值为圆心坐标和半径构成的三维数组
circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 20, param1= 300,param2= 100,minRadius= 10, maxRadius= 800)
print(circles)
if circles is not None:
circles = np.uint16(np.around(circles))#在使用之前需要经此转化
a, b, c = circles.shape
print(a)
print(b)
print(c)
print(str(circles))
for i in range(b):
cv.circle(cimg, (circles[0][i][0], circles[0][i][1]), circles[0][i][2], (0, 0, 255), 3, cv.LINE_AA)
cv.circle(cimg, (circles[0][i][0], circles[0][i][1]), 2, (0, 255, 0), 3,
cv.LINE_AA) # draw center of circle
cv.imshow("circles", cimg)
cv.waitKey(0)
画圆Circle函数的使用
def circle(img, center, radius, color, thickness=..., lineType=..., shift=...) -> typing.Any:
img:为源图像指针
center:为画圆的圆心坐标
radius:为圆的半径
color:为设定圆的颜色,规则根据B(蓝)G(绿)R(红)
thickness:如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充
lineType:线条的类型。默认是8
shift:圆心坐标点和半径值的小数点位数(虽然官方文章上是这样写的,但是实际使用时却改变了圆的位置)
注意:
1、传入参数中,center将表示为(列,行),而不是我们习惯上认为的(行,列),如果没有注意到这一点的话,绘制出来的图像中点的位置将不正确
2、在使用HoughCircles函数获得圆的三维数组后,还需要使用 circles = np.uint16(np.around(circles))转化,如果没有这一点就会出现以下错误:
Traceback (most recent call last):
File "d:/pythonQt/openCV/test02.py", line 19, in <module>
cv.circle(cimg, (circles[0][i][0], circles[0][i][1]), circles[0][i][2], (0, 0, 255), 3, cv.LINE_AA)
cv2.error: OpenCV(4.5.2) :-1: error: (-5:Bad argument) in function 'circle'
> Overload resolution failed:
> - Can't parse 'center'. Sequence item with index 0 has a wrong type
> - Can't parse 'center'. Sequence item with index 0 has a wrong type
然上述参数有着改变坐标点和半径值的小数点的参数,但是在实际使用时却无法实现,所以只能求得整型数据的圆心,存在一定误差。