You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调优OpenCV的HoughCircles方法以检测图像中所有圆点?

问题

在一项经济实验室实验中,我生成了包含圆点的图像,希望通过计算机视觉算法统计圆点数量。我使用OpenCV的HoughCircles方法进行检测计数,代码可运行但漏检大量圆点:

import cv2 as cv
import numpy as np

filename = "graph_0.png"
src = cv.imread(cv.samples.findFile(filename), cv.IMREAD_COLOR)
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

gray = cv.medianBlur(gray, 5)

rows = gray.shape[0]

circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, rows / 8,
                    param1=100, param2=0.05,
                    minRadius=1, maxRadius=30)

if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        center = (i[0], i[1])
        # circle center
        cv.circle(src, center, 1, (0, 100, 100), 3)
        # circle outline
        radius = i[2]
        cv.circle(src, center, radius, (255, 0, 255), 3)

cv.imshow("detected circles", src)
cv.waitKey(0)

# number of detected circles
len(circles[0])

已识别圆点

我认为问题之一是多处圆点融合成较大蓝色区域,但算法甚至漏检了许多被空白完全包围的圆点。

我尝试调整HoughCircles的参数,例如:

circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, rows / 32,
                    param1=100, param2=0.05,
                    minRadius=1, maxRadius=30)

将第三个参数改为rows/32后,检测数量更接近实际,但误检情况严重:

调整参数后误检严重

请问如何提升圆点的正确识别率?是调整HoughCircles的参数,还是需要先进行更多图像变换预处理?


解决方案

提升圆点识别率需要预处理优化+参数精细化调整结合,以下是具体可落地的步骤:

一、图像预处理优化

  1. 颜色分割替代灰度转换
    你的圆点是蓝色,直接提取蓝色区域比转灰度更精准,能过滤背景干扰:

    # 提取蓝色区域(可根据实际蓝色深浅微调阈值)
    lower_blue = np.array([100, 0, 0])
    upper_blue = np.array([255, 100, 100])
    mask = cv.inRange(src, lower_blue, upper_blue)
    # 用形态学开运算分离轻微粘连的圆点
    kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3,3))
    mask = cv.morphologyEx(mask, cv.MORPH_OPEN, kernel)
    
  2. 调整模糊策略
    原代码用medianBlur(5)可能过度模糊小圆点,换成3x3的中值模糊更适合保留小圆点边缘:

    gray = cv.medianBlur(mask, 3)
    

二、HoughCircles参数精细化调整

  1. param2:核心阈值控制
    你当前设的0.05过低,导致大量误检。这个参数是圆心检测的累加器阈值,值越高检测越严格,建议从20-50开始测试,逐步微调找到漏检和误检的平衡点。
  2. minDist:圆心最小距离
    rows/32太小,会让算法把很近的噪声识别成圆心。建议设为圆点直径的1.2-1.5倍,比如圆点半径是5,minDist就设为12左右。
  3. minRadius和maxRadius:缩小范围
    不要设过大的范围,根据图像中圆点的实际大小调整,比如实际圆点半径在3-10之间,就设minRadius=3, maxRadius=10,过滤掉不符合大小的误检区域。

调整后的示例参数:

circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, dp=1, minDist=12,
                          param1=80, param2=30,
                          minRadius=3, maxRadius=10)

三、备选方案:连通域分析

如果HoughCircles效果始终不理想,可以尝试用连通域分析统计圆点,对粘连不太严重的场景更稳定:

# 基于预处理后的mask图像
contours, _ = cv.findContours(mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
count = 0
for cnt in contours:
    # 计算轮廓圆形度,过滤非圆形区域
    area = cv.contourArea(cnt)
    perimeter = cv.arcLength(cnt, True)
    if perimeter == 0:
        continue
    circularity = 4 * np.pi * (area / (perimeter ** 2))
    # 圆形度接近1为标准圆形,可根据实际调整阈值
    if circularity > 0.7:
        count +=1
print("圆点数量:", count)

内容的提问来源于stack exchange,提问作者Johannes Walter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 11:45:30