基于OpenCV的含噪部分圆形检测及大小圆计数优化问题
问题解决:OpenCV圆检测优化方案
问题分析
现有代码无法检测图像顶部的部分圆形,且右侧圆形检测不准确,核心原因是HoughCircles参数设置不合理,以及未针对部分圆做算法适配,同时预处理步骤未充分强化圆的边缘特征。
关键修改点
- 替换圆检测算法:使用
cv2.HOUGH_GRADIENT_ALT替代cv2.HOUGH_GRADIENT,该算法对部分截断的圆形检测适配性更强。 - 优化预处理流程:增加二值化步骤,强化圆与背景的对比度,消除灰度噪声。
- 调整核心参数:
param1:降低Canny边缘检测高阈值,确保部分圆的边缘能被捕捉。param2:针对ALT算法设置为0.8(范围0-1),平衡检测精度与召回率。minDist:缩小最小圆心间距,适配顶部密集的部分圆。minRadius/maxRadius:微调半径范围,避免漏掉边缘圆。
修改后完整代码
import cv2 import numpy as np # 加载图像 image = cv2.imread(r'c:\Users\user\Downloads\circles.tif', cv2.IMREAD_GRAYSCALE) # 预处理:二值化(反转黑白,强化圆边缘) ret, thresh = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV) # 高斯模糊降噪 blurred = cv2.GaussianBlur(thresh, (5, 5), 0) # 使用HOUGH_GRADIENT_ALT检测圆,适配部分圆 circles = cv2.HoughCircles( blurred, cv2.HOUGH_GRADIENT_ALT, dp=1.2, minDist=30, param1=100, param2=0.8, minRadius=10, maxRadius=60 ) if circles is not None: circles = np.uint16(np.around(circles)) # 创建分离图像 smaller_circles_image = np.zeros_like(image) larger_circles_image = np.zeros_like(image) # 遍历检测到的圆 for i in circles[0, :]: x, y, radius = i[0], i[1], i[2] # 在原图绘制圆 cv2.circle(image, (x, y), radius, (0, 255, 0), 2) # 按半径分离 if radius < 25: cv2.circle(smaller_circles_image, (x, y), radius, 255, -1) else: cv2.circle(larger_circles_image, (x, y), radius, 255, -1) # 展示结果 cv2.imshow('Circles Detected', image) cv2.imshow('Smaller Circles', smaller_circles_image) cv2.imshow('Larger Circles', larger_circles_image) cv2.waitKey(0) cv2.destroyAllWindows() # 统计数量 num_smaller = len(circles[0, circles[0, :, 2] < 25]) num_larger = len(circles[0, circles[0, :, 2] >= 25]) print(f'小圆数量: {num_smaller}') print(f'大圆数量: {num_larger}') else: print('未检测到圆形')
效果说明
- 替换为
HOUGH_GRADIENT_ALT算法后,顶部的部分圆形能被准确识别,该算法通过梯度方向的匹配,对不完整圆的检测鲁棒性更强。 - 二值化预处理消除了图像中的灰度干扰,让圆的边缘更清晰,减少了误检。
- 参数调整后,右侧的圆形检测结果更准确,不会出现重复或错误标记。
内容的提问来源于stack exchange,提问作者lim
相关产品推荐
相关产品推荐

