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()
在实际应用中,可能需要根据不同的图像特点,对霍夫圆变换的参数(如 param1
、param2
、minRadius
、maxRadius
等)进行多次调整,以达到最佳的圆检测效果。
作者:普通网友