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()
相关推荐
Daydream.V21 小时前
基于Opencv和Dlib的人脸换脸实现
人工智能·opencv·计算机视觉·仿射变换·换脸·视频换脸·图片换脸
Westward-sun.1 天前
背景建模详解与OpenCV实现:从原理到代码实战
人工智能·opencv·计算机视觉
学习永无止境@1 天前
Sobel边缘检测的MATLAB实现
图像处理·opencv·算法·计算机视觉·fpga开发
纤纡.1 天前
基于 OpenCV 与 MediaPipe/Dlib 的计算机视觉实战:手势识别、仿射变换与 AI 换脸全解析
人工智能·opencv·计算机视觉
qq_385999081 天前
Win7 64 位 + MinGW64 + CMake + OpenCV
opencv
Westward-sun.1 天前
OpenCV实战:摄像头实时文档扫描与透视矫正
人工智能·opencv·计算机视觉
不懒不懒1 天前
《从仿射变换到实时手势识别:构建完整换脸与手势交互系统的全流程指南》
人工智能·opencv·计算机视觉
sali-tec1 天前
C# 基于OpenCv的视觉工作流-章46-矩形卡尺
图像处理·人工智能·opencv·算法·计算机视觉
Gary jie2 天前
OpenClaw4月更新的梦境记忆巩固系统
人工智能·深度学习·opencv·目标检测·机器学习·长短时记忆网络
Westward-sun.2 天前
OpenCV 实战:基于 SIFT 算法实现指纹图像验证
人工智能·opencv·计算机视觉