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

使用Circle Hough Transform检测圆形时遇到异常问题

霍夫圆变换统计硬币数量结果异常问题

我在使用霍夫圆变换统计二值图像中的圆形(硬币)数量时遇到问题,变换后的结果不符合预期。

原始二值图像:binary image

变换后图像:transformed image

相关代码如下:

import numpy as np
import cv2
from skimage import io, filters, measure
from skimage.filters import threshold_otsu, threshold_local
from scipy import ndimage
import matplotlib.pyplot as plt
import math


def Countcoins(img):
    im2 = cv2.resize(img, (2000, 2000), interpolation = cv2.INTER_LINEAR)
    b,g,r = cv2.split(im2) 
    r = cv2.GaussianBlur(r, (25,25), 0)
    g = cv2.GaussianBlur(g, (25,25), 0)
    b = cv2.GaussianBlur(b, (25,25), 0)
    r = cv2.medianBlur(r, 15)
    g = cv2.medianBlur(g, 15)
    b = cv2.medianBlur(b, 15)

    
    ret_red, coins_red = cv2.threshold(r, 0, 255, cv2.THRESH_OTSU) 
    ret_green, coins_green = cv2.threshold(g, 0, 255, cv2.THRESH_OTSU) 
    ret_blue, coins_blue = cv2.threshold(b, 0, 255, cv2.THRESH_OTSU) 


    image_merge = cv2.merge([coins_red, coins_green, coins_blue]) 
    im_gray = cv2.cvtColor(image_merge, cv2.COLOR_BGR2GRAY)
    im_gray = np.where(im_gray != im_gray[0,0], 255, 0)
    im_gray = np.asarray(im_gray, dtype="uint8")*255
    im_gray = cv2.morphologyEx(im_gray, cv2.MORPH_CLOSE,  np.ones((6, 6), np.uint8), iterations=5) 
    plt.imshow(im_gray, cmap = 'grey')
    plt.colorbar(shrink=0.8) 
    plt.show()

    im_gray = np.asarray(im_gray, dtype="uint8")*255
    circles = cv2.HoughCircles(im_gray,cv2.HOUGH_GRADIENT,1,250,param1 = 30, param2 = 5,minRadius=0,maxRadius=0)
    circles = np.uint8(np.around(circles))
    for i in circles[0,:]:
        # draw the outer circle
        cv2.circle(im2,(i[0],i[1]),i[2],(0,255,0),20)
        # draw the center of the circle
        cv2.circle(im2,(i[0],i[1]),2,(0,0,255),20)

    print('硬币数量: ' + str(len(circles[0,:])))
    plt.imshow(im2)


im = cv2.imread('coins2.jpg')
Countcoins(im)

问题分析与修复方案

1. 二值图像重复放大导致数据损坏

代码中im_gray = np.asarray(im_gray, dtype="uint8")*255执行了两次:第一次在二值化后已经将图像转为0/255的二值格式,第二次重复乘255会导致uint8类型数据溢出(超过255的部分取模变为0),直接破坏了二值图像的有效性。

修复:删除第二次的重复放大代码,保留第一次即可。

2. 霍夫圆变换参数设置不合理

  • param2=5阈值过低:该参数是累加器阈值,值越低会检测到越多假阳性圆,导致结果中出现大量无效小圆圈。
  • minDist=250过大:最小圆心距离设置超过了硬币实际间距,会漏掉相邻的硬币。
  • minRadius=0, maxRadius=0:自动检测半径结合低阈值,会生成大量无意义的小半径圆。

修复:调整参数适配硬币特征:

circles = cv2.HoughCircles(
    im_gray,
    cv2.HOUGH_GRADIENT,
    dp=1,
    minDist=50,  # 缩小最小圆心距离,适配硬币密度
    param1=50,   # 提高边缘检测阈值,减少噪声干扰
    param2=30,   # 提高累加器阈值,过滤假阳性
    minRadius=50,  # 根据硬币实际大小设置最小半径
    maxRadius=200  # 设置最大半径
)

3. 预处理步骤冗余

对RGB三个通道分别做高斯模糊+中值模糊是冗余操作,直接对灰度图处理即可,减少计算量同时避免通道合并的干扰。

4. 颜色空间显示失真

OpenCV读取的图像是BGR格式,matplotlib默认用RGB显示,直接plt.imshow(im2)会导致颜色偏色,需要转换颜色空间。


优化后的完整代码

import numpy as np
import cv2
import matplotlib.pyplot as plt

def Countcoins(img):
    im2 = cv2.resize(img, (2000, 2000), interpolation=cv2.INTER_LINEAR)
    # 直接转灰度图处理,减少冗余步骤
    im_gray = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)
    im_gray = cv2.GaussianBlur(im_gray, (25,25), 0)
    im_gray = cv2.medianBlur(im_gray, 15)
    
    # Otsu阈值二值化,反转图像让硬币区域为白色
    ret, im_binary = cv2.threshold(im_gray, 0, 255, cv2.THRESH_OTSU)
    im_binary = cv2.bitwise_not(im_binary)
    im_binary = cv2.morphologyEx(im_binary, cv2.MORPH_CLOSE, np.ones((6,6), np.uint8), iterations=5)
    
    plt.imshow(im_binary, cmap='grey')
    plt.colorbar(shrink=0.8)
    plt.show()
    
    # 霍夫圆变换
    circles = cv2.HoughCircles(
        im_binary,
        cv2.HOUGH_GRADIENT,
        dp=1,
        minDist=50,
        param1=50,
        param2=30,
        minRadius=50,
        maxRadius=200
    )
    
    if circles is not None:
        circles = np.uint16(np.around(circles))
        for i in circles[0,:]:
            cv2.circle(im2, (i[0],i[1]), i[2], (0,255,0), 10)
            cv2.circle(im2, (i[0],i[1]), 2, (0,0,255), 10)
        print('硬币数量: ' + str(len(circles[0,:])))
    else:
        print('未检测到硬币')
    
    # 转换颜色空间适配matplotlib显示
    plt.imshow(cv2.cvtColor(im2, cv2.COLOR_BGR2RGB))
    plt.show()

im = cv2.imread('coins2.jpg')
Countcoins(im)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:55:35