霍夫圆检测算法
[[01-霍夫圆检测算法]]
任务二
编写霍夫圆检测算法函数,检测图片中的圆的位置和参数
函数格式如下:
1 2 3 4 5 6 7 8
| def detect_circles(img_path): """ 输入:图片路径 输出:[ {'center': (x,y), 'radius': r}, ... # 按半径从大到小排序 ]
|
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| import cv2 import numpy as np
def detect_circles(img_path): image = cv2.imread(img_path) if image is None: raise ValueError("无法读取图片,请检查路径是否正确")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (9, 9), 2)
circles = cv2.HoughCircles( blurred, cv2.HOUGH_GRADIENT, dp=1.2, minDist=40, param1=40, param2=40, minRadius=40, maxRadius=150 )
if circles is None: return [], image
circles = np.round(circles[0, :]).astype("int") circles = sorted(circles, key=lambda x: x[2], reverse=True)
result = [{'center': (x, y), 'radius': r} for (x, y, r) in circles]
for circle in circles: center = (circle[0], circle[1]) radius = circle[2] cv2.circle(image, center, radius, (0, 255, 0), 4) cv2.rectangle(image, (center[0] - 5, center[1] - 5), (center[0] + 5, center[1] + 5), (0, 128, 255), -1)
return result, image
if __name__ == "__main__": result, image_with_circles = detect_circles("mission2/H.png") if result: for circle in result: print(f"圆心: {circle['center']}, 半径: {circle['radius']}") cv2.imshow('Detected Circles', image_with_circles) cv2.waitKey(0) cv2.destroyAllWindows() else: print("未检测到圆")
|
代码思路
先使用imread()函数读取指定路径的图片数据,保存在变量image中,如果无法读取,返回错误提示;若正常读取,先对图片数据进行预处理,因为霍夫圆变换检测函数HoughCircles()需要输入灰度图片,所以先使用cvtColor()函数转化为灰度图像,然后通过GaussianBlur()函数减少噪声,将预处理结果保存在blurred变量中。最后使用使用HoughCircles()函数对图片进行检测。期间要对 dp
,minDist
,param1
,param2
, minRadius
, maxRadius
六个参数不断进行调整使得输出结果理想,最后返回结果。
代码解释
根据题目要求,函数detect_circles()的输入值img_path
是图片的路径
1
| image = cv2.imread(img_path)
|
通过cv2.imread() 函数将img_path
路径的图片文件加载为 NumPy 数组,数组中的每个元素分别表示像素值的BGR数值
1 2
| if image is None: raise ValueError("无法读取图片,请检查路径是否正确")
|
检查图片是否成功加载,当imread返回值为空(None)时,说明图片路径无效或文件损坏,抛出异常提示用户。
1
| gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
因为后面的HoughCircles()
函数的输入需要为灰度图,所以将彩色图像转换为灰度图像。
1
| blurred = cv2.GaussianBlur(gray, (9, 9), 2)
|
对灰度图像进行高斯模糊处理,参数(9, 9)表示卷积核大小,2为标准差,目的是减少噪声。
1 2 3 4 5 6 7 8 9 10
| circles = cv2.HoughCircles( blurred, cv2.HOUGH_GRADIENT, dp=1.2, minDist=40, param1=40, param2=40, minRadius=40, maxRadius=150 )
|
使用霍夫圆变换检测圆,使用HoughCircles()方法
cv2.HoughCircles(image, method, dp, minDist, param1= x , param2= x , minRadius= x , maxRadius= x )
dp
# 累加器分辨率与图像分辨率的比值
minDist
# 检测到的圆心之间的最小距离
param1
# Canny 边缘检测的高阈值
param2
# 累加器阈值,较小的值将检测到更多的圆
minRadius
# 圆的最小半径
maxRadius
# 圆的最大半径
其中
dp=1
表示累加器和输入图像具有相同的分辨率,dp=2
表示累加器的宽高是输入图像的一半。
HoughCircles()方法的返回值是一个列表。
1 2
| if circles is None: return []
|
如果未检测到圆(circles为None),返回空列表。
1 2
| circles = np.round(circles[0, :]).astype("int") circles = sorted(circles, key=lambda x: x[2], reverse=True)
|
将检测到的圆坐标和半径四舍五入并转换为整数类型。
按照半径从大到小对圆进行排序。
1
| result = [{'center': (x, y), 'radius': r} for (x, y, r) in circles]
|
构建包含圆心和半径信息的字典列表,方便后面的绘制和输出。
1 2 3 4 5
| for circle in circles: center = (circle[0], circle[1]) radius = circle[2] cv2.circle(image, center, radius, (0, 255, 0), 4) cv2.rectangle(image, (center[0] - 5, center[1] - 5), (center[0] + 5, center[1] + 5), (0, 128, 255), -1)
|
对圆心和圆进行绘制。
返回结果。
运行结果
第一张图片


第二张图片

![[Pasted image 20250317223118.png]]
opencv #二维码 #QR #二维码识别
opencv #霍夫圆 #检测 #opencv #python