霍夫圆检测原理及使用案例(带调参过程)

在工业检测和机器视觉等领域,传统图像处理技术依然是不可或缺的重要方法。特别是圆形目标的检测和定位,传统图像处理技术的能够提供高效且精确的解决方案。本文将详细探讨如何使Python编程语言和OpenCV库,结合霍夫圆算法实现圆形目标的检测。此外,本文提供了调参的具体过程。觉得可以的话,点赞收藏哈。本人励志成为一名大博主,你的支持就是我最大的动力!!

目录

1 霍夫圆检测原理

1.1 检测原理

1.2 函数参数解释

2 使用案例

2.1 调参顺序

2.2 调参实例

2.2.1 原始代码

2.2.2 初步调参

2.2.3 最终调参

1 霍夫圆检测原理

1.1 检测原理

   圆的解析方程: (x - a)^2 + (y - b)^2 = r^2,参数空间: (a, b, r),其中(a, b)表示圆心坐标,r表示半径。

步骤如下:

1. 边缘检测:

对输入图像进行边缘检测,常用的方法有Canny算子、Sobel算子等,得到二值化的边缘图像,边缘点像素值为1,非边缘点像素值为0。

2.计算梯度:

对边缘图像计算梯度幅值和方向,梯度幅值反映边缘强度,梯度方向指向圆心

3.参数空间投票:

对每个边缘点(x, y),根据其梯度方向和预设的半径范围,计算可能的圆心坐标(a, b),将(a, b, r)对应的参数空间的累加器加1,表示一次投票

4. 查找局部最大值:

在参数空间的累加器中查找局部最大值,超过设定阈值的局部最大值对应检测到的圆,局部最大值的坐标(a, b, r)即为检测到的圆的参数。

5. 圆心和半径的确定:

对于每个检测到的圆,以(a, b)为圆心,r为半径,在原图像上绘制圆。

1.2 函数参数解释

circles = cv2.HoughCircles(GrayImage, cv2.HOUGH_GRADIENT, 1, minDist=20, param1=70, param2=50, minRadius=20, maxRadius=80)
  • GrayImage: 输入图像,单通道、灰度图像。

  • cv2.HOUGH_GRADIENT:表示使用梯度信息进行圆检测。

  • dp: 累加器分辨率与图像分辨率的反比。dp = 1 时,累加器的分辨率与图像分辨率相同;dp = 2 时,累加器的宽高都被减半。通常设置为 1 或 2。调整建议:增大 dp 可以减少计算量,但可能导致漏检;减小 dp 可以提高检测精度,但计算量增加。

  • minDist: 检测到的圆心之间的最小距离。如果两个圆心之间的距离小于该值,则认为它们是同一个圆。调整建议:根据圆之间的实际距离设置。增大 minDist 可以避免重复检测,但可能漏检一些圆;减小 minDist 可以检测更多的圆,但可能出现重复检测。

  • param1: Canny 边缘检测的高阈值,低阈值是高阈值的一半。调整建议:增大 param1 可以减少边缘点数,提高检测速度,但可能漏检一些圆;减小 param1 可以增加边缘点数,提高检测准确性,但速度变慢。

  • param2: 累加器的阈值。一个圆对应的累加器值超过该阈值时,才被认为是真正的圆。调整建议:增大 param2 可以提高检测精度,但可能漏检一些圆;减小 param2 可以检测更多的圆,但可能出现误检。

  • minRadius: 圆的最小半径。调整建议:根据待检测圆的实际最小尺寸设置。

  • maxRadius: 圆的最大半径。调整建议:根据待检测圆的实际最大尺寸设置。

2 使用案例

2.1 调参顺序

  • 先调整 dp 和 minDist,使检测到的圆的数量和位置大致正确。
  • 调整 param1 和 param2,使检测结果更加准确,同时尽量避免漏检和误检。
  • 最后根据实际需求调整 minRadius 和 maxRadius,限定检测圆的大小范围。

2.2 调参实例

2.2.1 原始代码

原始图像如下所示:

原始代码如下:

import cv2
import numpy as np
import time
if __name__ == "__main__":
    img=cv2.imread(r'C:\Users\Admin\Desktop\xiangmu\222222.png')
    t1=time.time()
    GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    circles = cv2.HoughCircles(GrayImage, cv2.HOUGH_GRADIENT, 1, 40, param1=70, param2=30, minRadius=0,maxRadius=0)
    t2=time.time()
    print("运行时间:",t2-t1)

    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        x,y,r=i[0],i[1],i[2]
        #draw the outer circle
        cv2.circle(img,(x,y),r,(0,255,0),2)
        cv2.circle(img,(x,y),2,(0,0,255),3)
    cv2.imshow("img",img)
    cv2.waitKey()

运行结果:

2.2.2 初步调参

调整内容:

  • 加入均值滤波

  • minDist改为20(根据圆之间的实际距离设置。)

  • param2改为50(提高检测精度,避免误检)

  • minRadius改为20,maxRadius改为80(根据待检测圆的实际最小、最大尺寸设置。)

代码如下:

import cv2
import numpy as np
import time

if __name__ == "__main__":
   
    image = cv2.imread(r'C:\Users\Admin\Desktop\xiangmu\222222.png')
    t1 = time.time()
    GrayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    GrayImage = cv2.blur(GrayImage, (7, 7))  # 均值滤波 滤除背景噪声
    circles = cv2.HoughCircles(GrayImage, cv2.HOUGH_GRADIENT, 1, minDist=20, param1=70, param2=50, minRadius=20, maxRadius=80)
    t2 = time.time()
    print("运行时间:", t2 - t1)  # 只统计霍夫圆检测时间

    # 这里进行圆绘制
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        x, y, r = i[0], i[1], i[2]
        # draw the outer circle
        cv2.circle(image, (x, y), r, (0, 255, 0), 2)
        cv2.circle(image, (x, y), 2, (0, 0, 255), 3)
    cv2.imshow("img1", image)
    cv2.waitKey()

运行结果如下:

2.2.3 最终调参

调整内容:

  • 加入均值滤波

  • minDist改为70(根据圆之间的实际距离设置。)

  • param2改为40(提高检测精度,避免误检)

  • minRadius改为30,maxRadius改为60(根据待检测圆的实际最小、最大尺寸设置。)

代码如下:

import cv2
import numpy as np
import time


def hough_circle_detection(image_path):
    # 读取图像
    # img = cv2.imread(image_path)
    img= cv2.imread(r'C:\Users\Admin\Desktop\xiangmu\222222.png')
    # 图像缩放
    # img = cv2.resize(img, None, fx=1, fy=1)

    # 转换为灰度图像
    gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 均值滤波以减少噪声
    gray_image = cv2.blur(gray_image, (9,9))

    # 霍夫圆检测
    t1 = time.time()
    circles = cv2.HoughCircles(
        gray_image,
        cv2.HOUGH_GRADIENT,
        dp=1,
        minDist=70,       # 设置最小圆心距离
        param1=70,        # Canny 边缘检测的高阈值
        param2=40,        # 圆心检测的阈值
        minRadius=30,     # 最小半径
        maxRadius=60      # 最大半径
    )
    t2 = time.time()
    print("运行时间:", t2 - t1)

    # 绘制检测到的圆
    if circles is not None:
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:
            x, y, r = i[0], i[1], i[2]
            # 绘制外圆
            cv2.circle(img, (x, y), r, (0, 255, 0), 2)
            # 绘制圆心
            cv2.circle(img, (x, y), 2, (0, 0, 255), 3)

    # 显示结果
    cv2.imshow("Detected Circles", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == "__main__":
    hough_circle_detection("test.png")  # 替换为你的图像路径

运行结果如下:

调试成功!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值