OpenCV 学习10-边缘检测(Edge Detection)

代码是AI辅助生成。

边缘检测是一种图像处理技术,用于识别图像中物体或区域的边界(边缘)。OpenCV提供了多种经典的边缘检测算法实现,广泛应用于图像处理、目标识别、特征提取等任务。

本文只是一个简单的学习笔记,请读者用不同的图像、参数进行试验,亲自感受

1、边缘是如何被检测出来的?

像素强度的突然变化是边缘的特征,在相邻像素中寻找这种变化来检测边缘。

本文主要列出两种重要的边缘检测算法:

  • Canny 边缘检测
  • Sobel 边缘检测

2、Canny 边缘检测

Canny 边缘检测算法 是由 John F. Canny 在 1986 年提出的一种多阶段边缘检测算法,是计算机视觉中最经典、最常用的边缘检测算法之一。

Canny算法包含5个关键步骤:

  • 高斯滤波去噪
  • 计算梯度幅值和方向
  • 非极大值抑制
  • 双阈值检测
  • 滞后边缘跟踪

2.1 cv2.Canny() 函数

cv2.Canny() 是 OpenCV 中用于执行 Canny 边缘检测 的核心函数,能够从图像中提取出清晰、连续的边缘轮廓。

函数定义

复制代码
edges = cv2.Canny(image, threshold1, threshold2, apertureSize=None, L2gradient=None)
  • 返回值

    返回一个 二值图像(NumPy 数组)

    像素值255表示检测到的边缘点,0表示非边缘点

  • 参数说明

参数 类型 说明
image NumPy 数组 输入图像,灰度图(Grayscale)。如果是彩色图用 cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 转换
threshold1 float 低阈值,用于弱边缘检测
threshold2 float 高阈值,用于强边缘检测,必须大于 threshold1。强梯度超过此值才被认为是"真实边缘"
pertureSize int (可选) Sobel 算子的孔径大小,用于计算图像梯度。默认为 3,可选 3~7 的奇数
L2gradient bool (可选) 是否使用更精确的 L2 范数计算梯度幅值

2.2 代码示例

复制代码
import cv2
import numpy as np

# 1.读取图像并转为灰度图
img = cv2.imread('img/dog.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 2.应用 Canny 边缘检测
canny = cv2.Canny(gray, threshold1=50, threshold2=150, apertureSize=3, L2gradient=False)

# 显示结果
cv2.imshow('Canny Edge Detection', canny)
cv2.waitKey(0)
cv2.destroyAllWindows()

3、Sobel 边缘检测

Sobel 边缘检测是一种经典的基于梯度的图像边缘检测方法,广泛应用于计算机视觉和图像处理领域。它通过计算图像在水平和垂直方向上的梯度来检测边缘。

Sobel 算子能够检测出由像素强度突然变化所形成的边缘。Sobel就是通过一个"卷积核"在图像上滑动,计算:"中心像素与其周围像素在水平和垂直方向上,灰度值变化得有多剧烈?" 变化剧烈的地方,就被标记为边缘。

3.1 cv2.Sobel() 函数

cv2.Sobel() 是 OpenCV 中用于图像梯度计算的函数,常用于边缘检测。它通过卷积操作计算图像在 x 方向(水平) 和/或 y 方向(垂直) 的梯度,从而突出灰度变化剧烈的区域。

函数定义

复制代码
dst = cv2.Sobel(src, ddepth, dx, dy, ksize=3, scale=1, delta=0, borderType=cv2.BORDER_DEFAULT)
  • 返回值
    dst:输出图像,与输入图像尺寸相同。
参数 类型 说明
src NumPy 数组 输入图像,灰度图
ddepth int(输出图像深度) 输出图像的数据深度,常用值 cv2.CV_8U cv2.CV_16S cv2.CV_32F cv2.CV_64F
dx int x 方向导数阶数(0 或 1) dx=1 表示检测垂直边缘(左右变化);dx=0 不启用
dy int y 方向导数阶数(0 或 1) dy=1 表示检测水平边缘(上下变化);dy=0 不启用
ksize int(可选) Sobel 核大小,默认为 3 必须是大于 1 的奇数(3, 5, 7...) 更大的值会增强抗噪能力但可能模糊边缘
scale float(可选) 缩放因子,卷积结果乘以此值,默认为 1
delta float(可选) 加到结果中的偏移量,默认为 0
borderType int(可选) 边界填充方式 cv2.BORDER_REFLECT cv2.BORDER_REPLICATE cv2.BORDER_CONSTANT

3.2 代码示例

python 复制代码
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像并转为灰度图
img = cv2.imread('img/dog.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 计算 x 方向梯度(垂直边缘)
sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobel_x = np.uint8(np.absolute(sobel_x))

# 计算 y 方向梯度(水平边缘)
sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
sobel_y = np.uint8(np.absolute(sobel_y))

# 合成总梯度幅值(L1 范数)
sobel_combined = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)

# 显示结果
titles = ['Original', 'Sobel X', 'Sobel Y', 'Sobel Combined']
images = [gray, sobel_x, sobel_y, sobel_combined]

for i in range(4):
    plt.subplot(2, 2, i+1), plt.imshow(images[i], cmap='gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

plt.show()
相关推荐
sali-tec2 天前
C# 基于OpenCv的视觉工作流-章27-图像分割
图像处理·人工智能·opencv·算法·计算机视觉
saoys2 天前
Opencv 学习笔记:腐蚀操作 + 轮廓标记 + 分水岭分割
笔记·opencv·学习
saoys2 天前
Opencv 学习笔记:距离变换(DIST_L1 算法实战 + 归一化)
笔记·opencv·学习
guygg883 天前
图像匹配技术:相关匹配、Hausdorff距离匹配与基于距离变换的Hausdorff距离匹配
图像处理·opencv·计算机视觉
AI科技星3 天前
物理世界的几何建构:论统一场论的本体论革命与概念生成
人工智能·opencv·线性代数·算法·矩阵
fie88893 天前
基于Matlab实现的指纹识别系统流程
opencv·计算机视觉·matlab
sali-tec3 天前
C# 基于OpenCv的视觉工作流-章26-图像拼接
图像处理·人工智能·opencv·算法·计算机视觉
智驱力人工智能3 天前
机场鸟类活动智能监测 守护航空安全的精准工程实践 飞鸟检测 机场鸟击预防AI预警系统方案 机场停机坪鸟类干扰实时监测机场航站楼鸟击预警
人工智能·opencv·算法·安全·yolo·目标检测·边缘计算
Σίσυφος19003 天前
OpenCV 之双线性插值
人工智能·opencv·计算机视觉
格林威4 天前
Baumer相机金属粉末铺粉均匀性评估:用于增材制造过程监控的 7 个实用技巧,附 OpenCV+Halcon 实战代码!
人工智能·opencv·视觉检测·制造·工业相机·智能相机·堡盟相机