7.6 圆形检测算法
7.6 圆形检测算法
基于霍夫变换的圆形检测的原理与直线检测类似,都是把图像空间中的问题转换到霍夫空间中去解决。图像空间中圆心为点(a,b),半径为r的圆,圆上任意一点可以表示为:
(x–a)2+(y–b)2=r2
在霍夫空间中,设横坐标为a,纵坐标为b,那么通过图像空间中点(x0,y0)的圆可以表示为:
(a–x0)2+(b–y0)2=r2
图像空间中一个圆形边界上有很多个点,对应到霍夫空间中就会有很多个圆。由于原图像中这些点都在同一个圆形上,那么转换后a,b必定也满足霍夫空间所有圆形的方程式。直观表现为许多点对应的圆都会相交于一个点,那么这个交点就是圆心(a,b)。在实现过程中,可以设置r的范围逐渐迭代计算,减小计算复杂度。
基于霍夫变换的圆形检测在opencv中的函数定义如下:
houghcircles(image, method, dp, mindist[, circles[, param1[, param2[,
minradius[, maxradius]]]]])
其中主要的参数如下。
? method:使用检测方法。目前唯一实现的方法是cv_hough_gradient。
? dp:累加器分辨率与图像分辨率的反比,通常取1。
? mindist:检测到的圆的中心之间的最小距离。如果参数太小,误报会高,如果太大漏报会高。
? param1:canny的阈值1。
? param2:canny的阈值2,霍夫变换的圆形检测会先使用canny进行边缘检测,因此需要设置canny相关阈值。
? minradius:最小圆半径。
? maxradius,最大圆半径。
下面我们演示如何检测路牌,相应的示例代码位于:
https://github.com/duoergun0729/adversarial_examples/blob/master/code/10-
case3.ipynb
首先我们加载测试图片,并转换成灰度图像。
img=cv2.imread("../picture/sign.jpeg")
gray_img=cv2.cvtcolor(img, cv2.color_rgb2gray)
show_img=gray_img.copy()
虽然基于霍夫变换的圆形检测本身就会使用canny边缘检测,但是为了展现这一过程,同时便于设置canny相关阈值,我们也使用canny手工进行边缘检测。
#canny的阈值
param1=50
param2=100
#canny边缘检测
edges = cv2.canny(gray_img, param1, param2)
#对二值图像进行反转,黑白颠倒
edges=cv2.bitwise_not(edges)
#构造空白图像
clean_img=np.ones_like(show_img)
最后使用霍夫变换进行圆形检测,其中设置检测的圆的半径在20到60之间。如图7-26所示,一共有四个子图,子图a是原始图像,子图b是使用canny算法进行了边缘检测,子图c是识别出的圆形,子图d是在原始图像上画上了识别出的圆形,可见达到了识别圆形路牌的目的。
# 霍夫圆变换
circles = cv2.houghcircles(gray_img,cv2.hough_gradient,1,
80,param1=param1,param2=param2,minradius=20,maxradius=60)
# 将检测的圆画出来
for i in circles[0, :]:
cv2.circle(show_img, (i[0], i[1]), i[2], (0, 255, 0), 2)
cv2.circle(clean_img, (i[0], i[1]), i[2], (0, 255, 0), 2)
图7-26 圆形检测示例
基于霍夫变换的圆形检测的原理与直线检测类似,都是把图像空间中的问题转换到霍夫空间中去解决。图像空间中圆心为点(a,b),半径为r的圆,圆上任意一点可以表示为:
(x–a)2+(y–b)2=r2
在霍夫空间中,设横坐标为a,纵坐标为b,那么通过图像空间中点(x0,y0)的圆可以表示为:
(a–x0)2+(b–y0)2=r2
图像空间中一个圆形边界上有很多个点,对应到霍夫空间中就会有很多个圆。由于原图像中这些点都在同一个圆形上,那么转换后a,b必定也满足霍夫空间所有圆形的方程式。直观表现为许多点对应的圆都会相交于一个点,那么这个交点就是圆心(a,b)。在实现过程中,可以设置r的范围逐渐迭代计算,减小计算复杂度。
基于霍夫变换的圆形检测在opencv中的函数定义如下:
houghcircles(image, method, dp, mindist[, circles[, param1[, param2[,
minradius[, maxradius]]]]])
其中主要的参数如下。
? method:使用检测方法。目前唯一实现的方法是cv_hough_gradient。
? dp:累加器分辨率与图像分辨率的反比,通常取1。
? mindist:检测到的圆的中心之间的最小距离。如果参数太小,误报会高,如果太大漏报会高。
? param1:canny的阈值1。
? param2:canny的阈值2,霍夫变换的圆形检测会先使用canny进行边缘检测,因此需要设置canny相关阈值。
? minradius:最小圆半径。
? maxradius,最大圆半径。
下面我们演示如何检测路牌,相应的示例代码位于:
https://github.com/duoergun0729/adversarial_examples/blob/master/code/10-
case3.ipynb
首先我们加载测试图片,并转换成灰度图像。
img=cv2.imread("../picture/sign.jpeg")
gray_img=cv2.cvtcolor(img, cv2.color_rgb2gray)
show_img=gray_img.copy()
虽然基于霍夫变换的圆形检测本身就会使用canny边缘检测,但是为了展现这一过程,同时便于设置canny相关阈值,我们也使用canny手工进行边缘检测。
#canny的阈值
param1=50
param2=100
#canny边缘检测
edges = cv2.canny(gray_img, param1, param2)
#对二值图像进行反转,黑白颠倒
edges=cv2.bitwise_not(edges)
#构造空白图像
clean_img=np.ones_like(show_img)
最后使用霍夫变换进行圆形检测,其中设置检测的圆的半径在20到60之间。如图7-26所示,一共有四个子图,子图a是原始图像,子图b是使用canny算法进行了边缘检测,子图c是识别出的圆形,子图d是在原始图像上画上了识别出的圆形,可见达到了识别圆形路牌的目的。
# 霍夫圆变换
circles = cv2.houghcircles(gray_img,cv2.hough_gradient,1,
80,param1=param1,param2=param2,minradius=20,maxradius=60)
# 将检测的圆画出来
for i in circles[0, :]:
cv2.circle(show_img, (i[0], i[1]), i[2], (0, 255, 0), 2)
cv2.circle(clean_img, (i[0], i[1]), i[2], (0, 255, 0), 2)
图7-26 圆形检测示例