当前位置: 首页 > news >正文

(纯新手教学)计算机视觉(opencv)实战八——四种边缘检测详解:Sobel、Scharr、Laplacian、Canny


边缘检测详解:Sobel、Scharr、Laplacian、Canny

边缘检测是图像处理和计算机视觉中的重要步骤,主要用于发现图像中亮度变化剧烈的区域,即物体的轮廓、边界或纹理特征。OpenCV 提供了多种常用的边缘检测算子,本教程将通过四种方法带大家详细学习:Sobel、Scharr、Laplacian、Canny


图片准备:

可直接使用下图,也可自备图片

以下所有处理后的结果:

一、Sobel 算子

1. 原理

Sobel 算子本质上是 一阶导数算子,通过对图像在 x方向和y方向 上分别求导,检测像素灰度变化最明显的部分。

  • dx=1, dy=0:只检测水平方向(垂直边缘)。

  • dx=0, dy=1:只检测垂直方向(水平边缘)。

  • 将两者结合,可以得到完整的边缘信息。

2. 函数原型

cv2.Sobel(src, ddepth, dx, dy[, ksize[, scale[, delta[, borderType]]]])

参数说明:

  • src:输入图像,可以是灰度图或彩色图。

  • ddepth:输出图像的深度,常用 cv2.CV_64F 保存负数梯度信息。

  • dx, dy:求导方向,dx=1 表示对x方向求导,dy=1 表示对y方向求导。

  • ksize:卷积核大小,常用3或5,必须为奇数。

参数说明
src输入图像,可以是灰度图或彩色图。
ddepth输出图像的深度(如 cv2.CV_64F 保留负值,-1 表示与原图一致)。
dxx方向导数阶数(1 表示对x方向求导)。
dyy方向导数阶数(1 表示对y方向求导)。
ksize卷积核大小(必须为奇数,常用 3、5、7)。
scale缩放因子,默认 1。
delta偏移量,默认 0。
borderType边界模式,默认 cv2.BORDER_DEFAULT

3. 示例代码

import cv2
img = cv2.imread('violet.jpg', flags=0)#不用灰度试试效果
img = cv2.resize(img,(800,500))
cv2.imshow('img',img)
cv2.waitKey(0)img_x_64 = cv2.Sobel(img,cv2.CV_64F,dx=1,dy=0)#默认int8改为float64,可保存负数
img_x_full = cv2.convertScaleAbs(img_x_64)#转换为绝对值,负数转换为正数
img_y_64 = cv2.Sobel(img,cv2.CV_64F,dx=0,dy=1)#默认int8改为float64,可保存负数
img_y_full = cv2.convertScaleAbs(img_y_64)#转换为绝对值,负数转换为正数
img_xy_sobel_full = cv2.addWeighted(img_x_full, 1, img_y_full, 1, 0)
cv2.imshow('img_xy_sobel_full',img_xy_sobel_full)
cv2.waitKey(0)

4. 特点

  • 简单高效,适合大多数情况。

  • 容易受噪声影响。


二、Scharr 算子

1. 原理

Scharr 算子是 Sobel 算子的改进版本,当卷积核大小为 3 时,它在近似旋转对称性方面更优,因此检测效果更清晰、平滑。

2. 函数原型

cv2.Scharr(src, ddepth, dx, dy)

相比 Sobel,参数更少,专门优化了 3×3 核的情况。

参数说明
src输入图像。
ddepth输出图像深度(如 cv2.CV_64F)。
dxx方向导数阶数(只能取1)。
dyy方向导数阶数(只能取1)。
scale缩放因子,默认 1。
delta偏移量,默认 0。
borderType边界模式,默认 cv2.BORDER_DEFAULT

3. 示例代码

img_x_64 = cv2.Scharr(img,cv2.CV_64F,dx=1,dy=0)#默认int8改为float64,可保存负数
img_x_full = cv2.convertScaleAbs(img_x_64)#转换为绝对值,负数转换为正数
img_y_64 = cv2.Scharr(img,cv2.CV_64F,dx=0,dy=1)#默认int8改为float64,可保存负数
img_y_full = cv2.convertScaleAbs(img_y_64)#转换为绝对值,负数转换为正数
img_xy_Scharr_full = cv2.addWeighted(img_x_full, 1, img_y_full, 1, 0)
cv2.imshow('img_xy_Scharr_full',img_xy_Scharr_full)
cv2.waitKey(0)

4. 特点

  • 对细节和纹理捕捉更好。

  • 运算速度和 Sobel 接近,但效果更佳。


三、Laplacian 算子

1. 原理

Laplacian 算子是 二阶导数算子,通过检测像素灰度的二阶变化,直接找出边缘。
与 Sobel、Scharr 不同,它不分方向,而是直接整体检测。

2. 函数原型

cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

参数说明:

  • src:输入图像。

  • ddepth:输出图像深度。

  • ksize:卷积核大小(一般取1、3、5)。

参数说明
src输入图像。
ddepth输出图像深度(如 cv2.CV_64F)。
dst输出图像(可选,通常不写)。
ksize卷积核大小,必须为正奇数(常用 1、3、5)。
scale缩放因子,默认 1。
delta偏移量,默认 0。
borderType边界模式,默认 cv2.BORDER_DEFAULT

3. 示例代码

img_lap = cv2.Laplacian(img,cv2.CV_64F)
img_lap_full = cv2.convertScaleAbs(img_lap)#转换为绝对值,负数转换为正数
cv2.imshow('img_lap_full',img_lap_full)
cv2.waitKey(0)

4. 特点

  • 可以快速检测边缘,但更容易受噪声干扰。

  • 常与高斯滤波结合使用(Laplacian of Gaussian, LoG)


四、Canny 算子

1. 原理

Canny 是经典的 多阶段边缘检测算法,相比前面三种更稳定、抗噪能力更强。其步骤包括:

  1. 高斯滤波去噪。

  2. 计算梯度强度与方向。

  3. 非极大值抑制(只保留局部最大边缘)。

  4. 双阈值检测(区分强边缘与弱边缘,并进行连接)。

2. 函数原型

cv2.Canny(image, threshold1, threshold2[, apertureSize[, L2gradient]])

参数说明:

  • image:输入图像,最好是灰度图。

  • threshold1:低阈值。

  • threshold2:高阈值。

  • apertureSize:Sobel 算子的核大小(默认3)。

参数说明
image输入图像(必须是单通道灰度图)。
threshold1低阈值,用于边缘连接。
threshold2高阈值,用于确定强边缘。
apertureSizeSobel 算子的卷积核大小(默认 3,可取 3、5、7)。
L2gradient计算梯度幅值的方法,默认为 False(使用 L1 范数),若为 True 使用 L2 范数,边缘更精确但计算量更大。

3. 示例代码

img_canny = cv2.Canny(img, threshold1=150, threshold2=230)#低,高
cv2.imshow('img_canny',img_canny)
cv2.waitKey(0)

4. 特点

  • 效果最优,边缘清晰完整。

  • 阈值选择影响很大。


五、效果对比总结

算子类型是否分方向抗噪性特点
Sobel一阶导数一般快速,适合简单边缘检测
Scharr一阶导数较好Sobel改进,细节更清晰
Laplacian二阶导数对噪声敏感,常与滤波结合
Canny多阶段检测最优,边缘清晰完整

六、实践建议

  1. 快速检测:用 Sobel 或 Scharr。

  2. 细节要求高:优先 Scharr。

  3. 检测轮廓:Laplacian + 高斯滤波。

  4. 稳定性优先:Canny。


这样,一张图像可以通过这四种算子分别得到不同风格的边缘信息,从而应用在 目标检测、图像分割、OCR、医学影像分析 等场景中。

http://www.dtcms.com/a/344536.html

相关文章:

  • Redis 678
  • 2025-08-22 Python进阶10——魔术方法
  • K8s的相关知识总结
  • X00238-非GNSS无人机RGB图像卫星图像视觉定位python
  • Django中间件自定义开发指南:从原理到实战的深度解析
  • 广播级讯道摄像机CCU后挂上的PGM、ENG、PROD音频旋钮是做什么用的?
  • js:beforeUnload这个方法能不能监听到关闭浏览器和刷新浏览器行为
  • 视觉语言大模型应用开发——基于 CLIP、Gemini 与 Qwen2.5-VL 的视频理解内容审核全流程实现
  • uniapp image标签展示视频第一帧
  • 【Linux】Vim编辑器:从入门到高效使用
  • MiniCPM-V4.0开源并上线魔乐社区,多模态能力进化,手机可用,还有最全CookBook!
  • WebRTC 结合云手机:释放实时通信与虚拟手机的强大协同效能
  • 聚焦科技前沿,华金证券与非凸科技共探数智交易新路径
  • 【GaussDB】全密态等值查询功能测试及全密态技术介绍
  • UNIKGQA论文笔记
  • SYBASE ASE、Oracle、MySQL/MariaDB、SQL Server及PostgreSQL在邮件/短信发送功能上的全面横向对比报告
  • 全景式综述|多模态目标跟踪全面解析:方法、数据、挑战与未来
  • #Datawhale 组队学习#8月-工作流自动化n8n入门-2
  • 基于51单片机的超声波液位检测OLED显示设计
  • MySQL InnoDB表空间深度解析:从原理到性能优化
  • Seaborn数据可视化实战:Seaborn与Plotly交互式图表入门
  • 图像处理中的伪影
  • ASPICE过程能力确定——度量框架
  • 美国对华科技政策思路变化:产业影响与投资逻辑解析
  • C/C++三方库移植到HarmonyOS平台详细教程
  • 2025年推理大模型有哪些以及优势对比
  • C++函数重载与引用详解
  • 线段树01
  • 合同差异智能比对,有效规避“阴阳合同”
  • 白名单过滤的文件上传如何bypass:boot2root靶机之fristileaks