Python|OpenCV-实现识别目标图像中的圆圈

以下是使用 Python 结合 OpenCV 库来实现识别目标图像中圆圈的详细代码示例及解释:

一、导入必要的库

首先,需要导入 opencv-python 库(用于图像处理操作)以及 numpy 库(用于处理数组数据,OpenCV 中很多图像数据结构基于 numpy 数组),代码如下:

python

import cv2
import numpy as np

二、读取图像

使用 cv2.imread 函数读取目标图像,该函数会返回一个 numpy 数组表示图像数据,参数传入图像文件的路径。需要确保图像文件路径正确且图像格式是 OpenCV 支持的(如 .jpg.png 等),示例代码如下:

python

# 替换为实际的图像文件路径
image_path = "your_image_path.jpg"  
image = cv2.imread(image_path)
if image is None:
    print("无法读取图像,请检查图像路径是否正确!")
    raise SystemExit

三、图像预处理

1.灰度转换
将彩色图像转换为灰度图像,这样可以简化后续处理流程并且减少计算量,因为在很多情况下,形状检测在灰度图上就足以完成。使用 cv2.cvtColor 函数来实现,代码如下:

python

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

2.高斯模糊
为了减少图像中的噪声对圆检测的影响,通常会对灰度图像进行高斯模糊处理。通过 cv2.GaussianBlur 函数来实现,可根据实际情况调整模糊核的大小等参数,示例代码如下:

python

# (5, 5) 是高斯模糊核的大小,可按需调整,1.5 是标准差,通常设为 0 也可自动计算
blurred = cv2.GaussianBlur(gray, (5, 5), 1.5)  

四、应用霍夫圆变换检测圆

使用 cv2.HoughCircles 函数来进行霍夫圆变换以检测图像中的圆,该函数的关键参数及含义如下:

python

circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, dp=1, minDist=20,
                           param1=50, param2=30, minRadius=0, maxRadius=0)
  • blurred:经过预处理(高斯模糊后的灰度图像)的输入图像。
  • cv2.HOUGH_GRADIENT:表示采用的霍夫圆变换方法,目前 OpenCV 中主要就是这种基于梯度的检测方法。
  • dp:累加器分辨率与图像分辨率的反比,例如 dp = 1 表示累加器和输入图像具有相同的分辨率,若 dp = 2 则累加器分辨率为图像分辨率的一半,常取值在 1 左右,可根据实际情况微调,这里设为 1
  • minDist:检测到的圆之间的最小距离,若两个圆的圆心距离小于该值,则认为它们是同一个圆,单位是像素,这里设为 20 像素,可根据图像中圆的分布情况调整。
  • param1:用于设置 Canny 边缘检测的高阈值(低阈值会自动按比例计算),在霍夫圆变换基于梯度检测时,边缘检测很关键,这里设为 50,可根据图像边缘情况调整。
  • param2:它是霍夫变换累加器的阈值,只有累加器中的值大于该阈值时,才认为检测到了一个圆,较小的值可能会检测到更多的假圆,较大的值可能会遗漏一些圆,这里设为 30,通常需要多次试验来确定合适值。
  • minRadius 和 maxRadius:分别设置要检测的圆的最小半径和最大半径(单位为像素),设为 0 表示不限制半径范围,可根据图像中圆的大致尺寸情况来设置具体的值进行筛选。
  • 由于 cv2.HoughCircles 函数返回的结果数据类型是 numpy 数组,且维度格式为 (1, N, 3)N 是检测到的圆的数量,3 表示每个圆有圆心横坐标、纵坐标和半径这三个参数),所以通常需要进行格式转换和数据提取,示例代码如下:

    python

    if circles is not None:
        circles = np.uint16(np.rounded(circles))
        for circle in circles[0, :]:
            # 提取圆心坐标和半径
            x, y, r = circle
            # 在原始图像上绘制圆
            cv2.circle(image, (x, y), r, (0, 255, 0), 2)
            # 在圆心处绘制一个小圆点(标记圆心)
            cv2.circle(image, (x, y), 2, (0, 0, 255), 3)
    

    五、显示结果图像

    使用 cv2.imshow 函数显示绘制了检测到的圆及圆心标记的图像,并且通过 cv2.waitKey 函数等待按键操作,最后使用 cv2.destroyAllWindows 函数关闭所有图像显示窗口,示例代码如下:

    python

    cv2.imshow("Detected Circles", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    完整的代码示例如下:

    python

    import cv2
    import numpy as np
    
    # 读取图像
    image_path = "your_image_path.jpg"
    image = cv2.imread(image_path)
    if image is None:
        print("无法读取图像,请检查图像路径是否正确!")
        raise SystemExit
    
    # 图像预处理
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 1.5)
    
    # 应用霍夫圆变换检测圆
    circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, dp=1, minDist=20,
                               param1=50, param2=30, minRadius=0, maxRadius=0)
    
    if circles is not None:
        circles = np.uint16(np.rounded(circles))
        for circle in circles[0, :]:
            x, y, r = circle
            cv2.circle(image, (x, y), r, (0, 255, 0), 2)
            cv2.circle(image, (x, y), 2, (0, 0, 255), 3)
    
    # 显示结果图像
    cv2.imshow("Detected Circles", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    在实际应用中,可能需要根据不同的图像特点,对霍夫圆变换的参数(如 param1param2minRadiusmaxRadius 等)进行多次调整,以达到最佳的圆检测效果。

    作者:普通网友

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python|OpenCV-实现识别目标图像中的圆圈

    发表回复