如何用Python修正代码以准确识别并统计图像中的彩色大圆圈
问题:准确统计图像中大彩色圆圈数量(排除小圆圈)
需分析包含多色圆圈的图像,仅统计大圆圈,排除每个大圆圈左上角的小圆圈。现有基于OpenCV和NumPy的检测代码结果错误:统计红色15个、蓝色10个、绿色1个,且可视化结果误识别了小圆圈,需修正代码以实现精准统计。
相关图像


原始代码
import cv2 import numpy as np def count_colored_circles(image_path): # Load image image = cv2.imread(image_path) if image is None: print("Error: Unable to load image.") return # Convert image to grayscale gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Apply Gaussian blur to reduce noise and improve circle detection blurred = cv2.GaussianBlur(gray, (5, 5), 0) # Detect circles circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, dp=1, minDist=1, param1=50, param2=30, minRadius=20, maxRadius=40) if circles is not None: circles = np.uint16(np.around(circles)) counts = {'red': 0, 'blue': 0, 'green': 0} for circle in circles[0, :]: # Extract region of interest (ROI) for each circle x, y, radius = circle roi = image[max(0, y-radius):min(y+radius, image.shape[0]), max(0, x-radius):min(x+radius, image.shape[1])] # Calculate the average color in the ROI avg_color = np.mean(roi, axis=(0, 1)) # Determine the color category based on the average color if avg_color[2] > avg_color[0] and avg_color[2] > avg_color[1]: color = 'red' elif avg_color[0] > avg_color[1] and avg_color[0] > avg_color[2]: color = 'blue' else: color = 'green' # Increment count for the detected color counts[color] += 1 # Print counts of each color print("Counts of each color:") for color, count in counts.items(): print(f"{color}: {count}") # Visualize detected circles (optional) for circle in circles[0, :]: x, y, radius = circle cv2.circle(image, (x, y), radius, (0, 255, 0), 2) cv2.imshow('Detected Circles', image) cv2.waitKey(0) cv2.destroyAllWindows() else: print("No circles detected.") # Provide the absolute path to the image file image_path = "D:/TBL9.PNG" # Replace "your_image.jpg" with the actual image filename count_colored_circles(image_path)
问题分析
- 霍夫圆检测参数不合理:
minDist=1过小,导致算法检测到大量紧邻大圆圈的小圆圈;minRadius和maxRadius范围未精准匹配大圆圈尺寸,小圆圈也被纳入检测范围。 - 颜色判断逻辑有缺陷:直接取整个圆圈ROI的平均颜色,小圆圈的颜色会干扰大圆圈的颜色判断,导致统计错误。
修正方案
- 调整霍夫圆检测参数:
- 增大
minDist至大圆圈直径的一半以上(如60),确保仅检测彼此间距足够的大圆圈 - 精准设置
minRadius和maxRadius(如30-40),过滤小圆圈 - 提高
param2阈值(如35),减少弱检测结果
- 增大
- 优化颜色判断:
- 取圆圈中心区域(而非整个ROI)的颜色平均值,避免小圆圈干扰
- 增加颜色差值阈值,提升颜色分类的准确性
修正后的代码
import cv2 import numpy as np def count_colored_circles(image_path): # 加载图像 image = cv2.imread(image_path) if image is None: print("Error: 无法加载图像。") return # 转换为灰度图 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 高斯模糊去噪 blurred = cv2.GaussianBlur(gray, (5, 5), 0) # 检测大圆圈:调整参数过滤小圆圈 circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, dp=1, minDist=60, param1=50, param2=35, minRadius=30, maxRadius=40) if circles is not None: circles = np.uint16(np.around(circles)) counts = {'red': 0, 'blue': 0, 'green': 0} for circle in circles[0, :]: x, y, radius = circle # 取圆圈中心区域(避免小圆圈干扰) center_size = radius // 2 roi = image[y-center_size:y+center_size, x-center_size:x+center_size] avg_color = np.mean(roi, axis=(0, 1)) # 优化颜色判断:增加差值阈值 b, g, r = avg_color if r > g + 20 and r > b + 20: color = 'red' elif b > g + 20 and b > r + 20: color = 'blue' elif g > r + 20 and g > b + 20: color = 'green' else: # 无法明确分类的跳过(可选) continue counts[color] += 1 # 输出统计结果 print("各颜色圆圈数量:") for color, count in counts.items(): print(f"{color}: {count}") # 可视化检测结果 for circle in circles[0, :]: x, y, radius = circle cv2.circle(image, (x, y), radius, (0, 255, 0), 2) cv2.imshow('检测到的大圆圈', image) cv2.waitKey(0) cv2.destroyAllWindows() else: print("未检测到圆圈。") # 图像路径 image_path = "D:/TBL9.PNG" count_colored_circles(image_path)
内容的提问来源于stack exchange,提问作者Mazhar Ali
相关产品推荐
相关产品推荐

