【进阶】霍夫圆变换

霍夫变换除了用来检测直线外,也能用来检测其他几何对象。实际上,只要是能够用一个参数方程表示的对象,都适合用霍夫变换来检测。

用霍夫圆变换来检测图像中的圆,与使用霍夫直线变换检测直线的原理类似。在霍夫圆变换中,需要考虑圆半径和圆心(x坐标、y坐标)共3个参数。在OpenCV中,采用的策略是两轮筛选。第1轮筛选找出可能存在圆的位置(圆心);第2轮再根据第1轮的结果筛选出半径大小。

与用来决定是否接受直线的两个参数“接受直线的最小长度(minLineLength)”和“接受直线时允许的最大像素点间距(MaxLineGap)”类似,霍夫圆变换也有几个用于决定是否接受圆的参数:圆心间的最小距离、圆的最小半径、圆的最大半径。

在OpenCV中,实现霍夫圆变换的是函数cv2.HoughCircles(),该函数将Canny边缘检测和霍夫变换结合。其语法格式为:

circles = cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])

● image:输入图像,即源图像,类型为8位的单通道灰度图像。

● method:检测方法。参数HOUGH_GRADIENT代表的是霍夫圆检测中两轮检测所使用的方法。

● dp:累计器分辨率,它是一个分割比率,用来指定图像分辨率与圆心累加器分辨率的比例。例如,如果dp=1,则输入图像和累加器具有相同的分辨率。

● minDist:圆心间的最小间距。该值被作为阈值使用,如果存在圆心间距离小于该值的多个圆,则仅有一个会被检测出来。因此,如果该值太小,则会有多个临近的圆被检测出来;如果该值太大,则可能会在检测时漏掉一些圆。

● param1:该参数是缺省的,在缺省时默认值为100。它对应的是Canny边缘检测器的高阈值(低阈值是高阈值的二分之一)。

● param2:圆心位置必须收到的投票数。只有在第1轮筛选过程中,投票数超过该值的圆,才有资格进入第2轮的筛选。因此,该值越大,检测到的圆越少;该值越小,检测到的圆越多。这个参数是缺省的,在缺省时具有默认值100。

● minRadius:圆半径的最小值,小于该值的圆不会被检测出来。该参数是缺省的,在缺省时具有默认值0,此时该参数不起作用。

● maxRadius:圆半径的最大值,大于该值的圆不会被检测出来。该参数是缺省的,在缺省时具有默认值0,此时该参数不起作用。

在调用函数cv2.HoughLinesCircles()之前,要对源图像进行平滑操作,以减少图像中的噪声,避免发生误判。

程序演示

import cv2
import numpy as np

origin = cv2.imread('chess.jpg', cv2.IMREAD_COLOR)

gray = cv2.cvtColor(origin, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, 5)

circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 200, param1=50, param2=30, minRadius=80, maxRadius=200)
circles = np.uint16(np.around(circles))

for i in circles[0, :]:
    cv2.circle(origin, (i[0], i[1],), i[2], (0, 0, 255), 6)
    cv2.circle(origin, (i[0], i[1],), 2, (0, 0, 255), 6)

cv2.imshow('circles', origin)

cv2.waitKey(0)
cv2.destroyAllWindows()

image.png