欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > OpenCV 边缘检测(Edge Detection)cv2.Canny

OpenCV 边缘检测(Edge Detection)cv2.Canny

2025/4/22 1:18:34 来源:https://blog.csdn.net/flyfish1986/article/details/147332518  浏览:    关键词:OpenCV 边缘检测(Edge Detection)cv2.Canny

OpenCV 边缘检测(Edge Detection)cv2.Canny

flyfish

import cv2video_path = 'input_video.mp4'
cap = cv2.VideoCapture(video_path)while True:ret, frame = cap.read()if not ret:break  # 视频结束# 转灰度frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 高斯模糊(减少噪声)blurred = cv2.GaussianBlur(frame_gray, (5, 5), 0)# 边缘检测**edges = cv2.Canny(blurred, threshold1=100, threshold2=200)  # Canny 算子参数# 可视化结果cv2.imshow('Original Frame', frame)cv2.imshow('Edges', edges)  # 显示边缘检测结果if cv2.waitKey(1) == ord('q'):breakcap.release()
cv2.destroyAllWindows()

解释

1. 边缘检测(Canny 算子)
edges = cv2.Canny(blurred, threshold1=100, threshold2=200)
  • cv2.Canny 函数
    OpenCV 中经典的边缘检测算法,通过梯度运算和阈值处理检测图像边缘。
  • 参数说明
    • blurred:输入的模糊后的灰度图像(减少噪声后效果更好)。
    • threshold1=100低阈值(用于检测弱边缘)。
    • threshold2=200高阈值(用于检测强边缘)。
      • 强边缘会被保留,弱边缘如果与强边缘相连也会被保留,否则被丢弃。
    • 返回值 edges 是单通道二值图像(0 表示非边缘,255 表示边缘)。
2. 显示边缘结果
cv2.imshow('Edges', edges)
  • 窗口显示
    新增一个窗口 Edges,显示检测到的边缘(黑白图像,白色为边缘)。
  • 同时显示原图
    cv2.imshow('Original Frame', frame) 可选保留,方便对比。

参数调整建议

(1) 阈值参数 threshold1threshold2
  • 默认值 100200:适用于大多数场景,但需根据视频内容调整。
  • 调整方向
    • 提高阈值(如 threshold1=150, threshold2=250):
      减少边缘检测的敏感度,抑制噪声干扰,但可能丢失细节。
    • 降低阈值(如 threshold1=50, threshold2=150):
      增加敏感度,检测更多边缘,但可能包含更多噪声。
(2) 高斯模糊的核大小
  • 当前设置 (5,5):平衡去噪和保留细节。
  • 调整方向
    • 增大核(如 (7,7):更强的去噪,但边缘可能更模糊。
    • 减小核(如 (3,3):保留更多细节,但噪声可能更明显。

扩展功能(可选)

1. 在原图上绘制边缘

如果希望将边缘叠加到原图上(彩色显示),可以这样做:

# 将边缘图转换为三通道图像(与原图合并)
edges_color = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
# 合并原图和边缘图(横向拼接)
combined = np.hstack((frame, edges_color))
cv2.imshow('Combined', combined)
2. 调整 Canny 的其他参数
  • apertureSize:Sobel 算子的核大小(默认 3,可选 5 增加边缘检测的鲁棒性):
    edges = cv2.Canny(blurred, 100, 200, apertureSize=5)
    

Canny 边缘检测是一种经典且广泛应用的边缘检测算法,它具有低错误率、高定位精度和抑制虚假边缘等优点。

1. 高斯平滑

在进行边缘检测之前,图像中可能存在噪声,这些噪声会干扰边缘的检测结果。因此,第一步通常是对图像进行高斯平滑处理,使用高斯滤波器来减少噪声。高斯滤波器是一个二维的高斯函数,它对图像中的每个像素及其邻域像素进行加权平均,使得噪声的影响得到抑制。具体来说,就是通过 cv2.GaussianBlur 这样的操作,将图像中的高频噪声去除,让图像变得更加平滑,为后续的边缘检测做准备。

2. 计算梯度强度和方向

经过高斯平滑后的图像,需要计算其梯度信息,因为边缘通常对应着图像中灰度值变化较大的区域,而梯度可以反映这种变化。一般使用 Sobel 算子分别在水平( x x x 方向)和垂直( y y y 方向)计算梯度。

  • 水平梯度计算:使用 3 × 3 3\times3 3×3 的 Sobel 算子 G x G_x Gx 与图像进行卷积操作,得到水平方向的梯度分量 G x G_x Gx
  • 垂直梯度计算:使用 3 × 3 3\times3 3×3 的 Sobel 算子 G y G_y Gy 与图像进行卷积操作,得到垂直方向的梯度分量 G y G_y Gy
  • 梯度强度计算:根据 G x G_x Gx G y G_y Gy 计算梯度的强度 G G G,计算公式为 G = G x 2 + G y 2 G=\sqrt{G_x^2 + G_y^2} G=Gx2+Gy2
  • 梯度方向计算:计算梯度的方向 θ \theta θ,计算公式为 θ = arctan ⁡ ( G y G x ) \theta=\arctan(\frac{G_y}{G_x}) θ=arctan(GxGy)。梯度方向通常被近似为四个方向之一: 0 ∘ 0^{\circ} 0 4 5 ∘ 45^{\circ} 45 9 0 ∘ 90^{\circ} 90 13 5 ∘ 135^{\circ} 135

3. 非极大值抑制

在计算得到梯度强度和方向后,图像中可能存在很多梯度强度较大的点,但这些点不一定都对应真正的边缘。非极大值抑制的目的是在局部范围内找出梯度强度的极大值点,将非极大值点的梯度值设为 0,从而细化边缘。具体步骤如下:

  • 对于每个像素点,根据其梯度方向,判断其在梯度方向上的相邻像素点。
  • 如果该像素点的梯度强度小于其相邻像素点的梯度强度,则将该像素点的梯度值设为 0;否则,保留该像素点的梯度值。

4. 双阈值检测和边缘连接

经过非极大值抑制后,仍然可能存在一些虚假的边缘点。双阈值检测通过设置两个阈值(低阈值 T l o w T_{low} Tlow 和高阈值 T h i g h T_{high} Thigh)来进一步筛选边缘点。具体步骤如下:

  • 强边缘点确定:将梯度强度大于高阈值 T h i g h T_{high} Thigh 的像素点标记为强边缘点,这些点肯定是边缘点。
  • 弱边缘点确定:将梯度强度介于低阈值 T l o w T_{low} Tlow 和高阈值 T h i g h T_{high} Thigh 之间的像素点标记为弱边缘点,这些点可能是边缘点,也可能是噪声。
  • 边缘连接:检查弱边缘点是否与强边缘点相连。如果弱边缘点与强边缘点相连,则将其标记为边缘点;否则,将其视为噪声并去除。

操作图像的示例代码

import cv2# 读取图像
image = cv2.imread('example.jpg', 0)  # 以灰度模式读取图像# 进行 Canny 边缘检测
edges = cv2.Canny(image, 100, 200)# 显示原始图像和边缘检测结果
cv2.imshow('Original Image', image)
cv2.imshow('Canny Edges', edges)# 等待按键事件
cv2.waitKey(0)# 关闭所有窗口
cv2.destroyAllWindows()

cv2.Canny 函数的第二个和第三个参数分别是低阈值和高阈值,你=可以根据实际情况调整这两个参数的值,以获得不同的边缘检测效果。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词