Python版本是Python3.7.3,OpenCV版本OpenCV.3.4.1,开发环境为PyCharm
16.4 霍夫圆环变换
霍夫变换除了用来检测直线外,也能用来检测其他几何对象。实际上,只要是能够用一个参数方程表示的对象,都适合用霍夫变换来检测。
用霍夫圆变换来检测图像中的圆,与使用霍夫直线变换检测直线的原理类似。在霍夫圆变换中,需要考虑圆半径和圆心(x坐标、y坐标)共3个参数。在OpenCV中,采用的策略是两轮筛选。第1轮筛选找出可能存在圆的位置(圆心);第2轮再根据第1轮的结果筛选出半径大小。
与用来决定是否接受直线的两个参数“接受直线的最小长度(minLineLength)”和“接受直线时允许的最大像素点间距(MaxLineGap)”类似,霍夫圆变换也有几个用于决定是否接受圆的参数:圆心间的最小距离、圆的最小半径、圆的最大半径。
在OpenCV中,实现霍夫圆变换的是函数cv2.HoughCircles(),该函数将Canny边缘检测和霍夫变换结合。其语法格式为:
circles=cv2.HoughCircles(image,
method,
dp,
minDist,
param1,
param2,
minRadius,
maxRadius)
式中参数与返回值的含义如下:
● image:输入图像,即源图像,类型为8位的单通道灰度图像。
● method:检测方法。截止到OpenCV 4.0.0-pre版本,HOUGH_GRADIENT是唯一可用的参数值。该参数代表的是霍夫圆检测中两轮检测所使用的方法。
● dp:累计器分辨率,它是一个分割比率,用来指定图像分辨率与圆心累加器分辨率的比例。例如,如果dp=1,则输入图像和累加器具有相同的分辨率。
● minDist:圆心间的最小间距。该值被作为阈值使用,如果存在圆心间距离小于该值的多个圆,则仅有一个会被检测出来。因此,如果该值太小,则会有多个临近的圆被检测出来;如果该值太大,则可能会在检测时漏掉一些圆。
● param1:该参数是缺省的,在缺省时默认值为100。它对应的是Canny边缘检测器的高阈值(低阈值是高阈值的二分之一)。
● param2:圆心位置必须收到的投票数。只有在第1轮筛选过程中,投票数超过该值的圆,才有资格进入第2轮的筛选。因此,该值越大,检测到的圆越少;该值越小,检测到的圆越多。这个参数是缺省的,在缺省时具有默认值100。
● minRadius:圆半径的最小值,小于该值的圆不会被检测出来。该参数是缺省的,在缺省时具有默认值0,此时该参数不起作用。
● maxRadius:圆半径的最大值,大于该值的圆不会被检测出来。该参数是缺省的,在缺省时具有默认值0,此时该参数不起作用。
● circles:返回值,由圆心坐标和半径构成的numpy.ndarray。
需要特别注意,在调用函数cv2.HoughLinesCircles()之前,要对源图像进行平滑操作,以减少图像中的噪声,避免发生误判。
该函数具有非常多的参数,在实际检测中可以根据需要设置不同的值。
eg1:使用HoughLinesCircles函数对一幅图像进行霍夫圆变换,并观察检测效果。
代码如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('chess.jpg',0)
imgo=cv2.imread('chess.jpg',-1)
o=cv2.cvtColor(imgo,cv2.COLOR_BGR2RGB)
oshow=o.copy()
img = cv2.medianBlur(img,5)
circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,300,param1=50,param2=30,minRadius=100,maxRadius=200)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(o,(i[0],i[1]),i[2],(255,0,0),12)
cv2.circle(o,(i[0],i[1]),2,(255,0,0),12)
plt.subplot(121)
plt.imshow(oshow)
plt.axis('off')
plt.subplot(122)
plt.imshow(o)
plt.axis('off')
plt.show()
运行上述程序,结果如下图所示,可以看到霍夫圆变换检测到了源图像中的三个圆。为了方便读者在纸质版图书上观察,本例中圆环和圆心都是用白色显示的,在实际使用中可以设置函数cv2.circle()中的颜色参数,显示不同的颜色。
在检测中,可能需要不断调整参数才能得到最优结果。例如,下图是参数为
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT,1,20,
param1=50, param2=30, minRadius=0, maxRadius=0)
时,针对图中的左图进行霍夫圆变换所得到的结果。如果仔细观察,可以看到下图
中绘制了非常多的圆和圆心。