计算机视觉--Opencv(边缘检测)

一、边缘检测的核心原理

图像的边缘本质上是像素灰度值发生剧烈变化的位置。在数字图像中,这种 "变化" 可以通过梯度运算来量化 ------ 梯度的大小代表变化的剧烈程度,梯度的方向代表变化的方向。

对于二维图像而言,梯度分为 X 方向(水平,左右)和 Y 方向(垂直,上下):

  • X 方向梯度:检测垂直边缘(像素值在水平方向突变)

  • Y 方向梯度:检测水平边缘(像素值在垂直方向突变)

注意:

梯度计算会产生正负值(比如从亮到暗为负,从暗到亮为正),但图像像素值的显示范围是 0-255(uint8 类型),负数会被直接截断为 0,导致部分边缘信息丢失。因此在实际操作中,需要将梯度结果转换为 64 位浮点型(CV_64F)保存正负值,再通过取绝对值还原完整的边缘信息。

二、边缘检测Sobel算子详解

Sobel 算子的核心是通过两个 3×3 的卷积核(分别对应 X、Y 方向),与图像进行卷积运算,计算出每个像素点的梯度值,梯度值越大,说明该点越可能是边缘。

代码如下:

1.读取图片并显示原图

python 复制代码
yuan = cv2.imread(r"C:\Users\LEGION\Desktop\497f7b3881df229ede103f77c0e30d5e.png")
cv2.imshow('yuan',yuan)
cv2.waitKey(0)

运行结果:

2. X方向边缘检测(直接使用默认类型,丢失负数信息)

python 复制代码
yuan_x = cv2.Sobel(yuan,-1,dx=1,dy=0)
cv2.imshow('yuan_x',yuan_x)
cv2.waitKey(0)

cv2.Sobel参数说明:

src: 输入图像;ddepth: 输出图像深度,-1表示与原图类型一致(uint8)

dx: X方向导数阶数(1表示计算X方向梯度);dy: Y方向导数阶数(0表示不计算)

运行结果:

3.X方向边缘检测(保留负数信息,还原完整边缘)

python 复制代码
# cv2.CV_64F:64位浮点型,可存储正负梯度值,避免信息丢失
yuan_x_64 = cv2.Sobel(yuan, cv2.CV_64F, dx=1, dy=0)
# cv2.convertScaleAbs:将浮点型结果转换为绝对值,并映射到0-255范围
yuan_x_full = cv2.convertScaleAbs(yuan_x_64)
cv2.imshow('X方向边缘(完整信息)', yuan_x_full)
cv2.waitKey(0)

cv2.CV_64F:64位浮点型,可存储正负梯度值,避免信息丢失

运行结果:

4.Y方向边缘检测(同理,保留负数信息)

python 复制代码
yuan_y = cv2.Sobel(yuan,-1,dx=0,dy=1)
cv2.imshow('yuan_y', yuan_y)
cv2.waitKey(0)

运行结果:

5.Y方向边缘检测(保留负数信息,还原完整边缘)

python 复制代码
yuan_y_64 = cv2.Sobel(yuan,cv2.CV_64F,dx=0,dy=1)#默认int8改为float64,可保存负数
yuan_y_full= cv2.convertScaleAbs(yuan_y_64)#转换为绝对值,负数转换为正数
cv2.imshow('yuan_y_full', yuan_y_full)
cv2.waitKey(0)

运行结果:

6.同时使用x,y方向的结果如何呢? (不建议使用!!!)

python 复制代码
yuan_xy = cv2.Sobel(yuan,-1,dx=1,dy=1)
cv2.imshow('yuan_xy', yuan_xy)
cv2.waitKey(0)

运行结果:

原因:dx=1、dy=1会让两个方向的梯度相互干扰,边缘模糊,检测效果差

7.加权融合X/Y方向边缘

python 复制代码
yuan_xy_full = cv2.addWeighted(yuan_x_full, 1, yuan_y_full, 1, 0)
    cv2.imshow('X+Y方向加权融合(推荐)', yuan_xy_full)
    cv2.waitKey(0)

cv2.addWeighted参数说明:

src1, alpha(权重1), src2, beta(权重2), gamma(亮度偏移)

这里权重都设为1,gamma=0,表示两个图像等权重融合

运行结果:

三、四种边缘检测算子

1.Sobel算子

代码如下:

python 复制代码
zl =cv2.imread(r"C:\Users\LEGION\Desktop\OIP-C.webp",0)
zl_x_64 = cv2.Sobel(zl,cv2.CV_64F,dx=1,dy=0)
zl_x_full=cv2.convertScaleAbs(zl_x_64)
zl_y_64 = cv2.Sobel(zl,cv2.CV_64F,dx=0,dy=1)
zl_y_full=cv2.convertScaleAbs(zl_y_64)
zl_xy_sobel_full = cv2.addWeighted(zl_x_full, 1,zl_y_full,1,0)
cv2.imshow('zl_xy_sobel_full',zl_xy_sobel_full)
cv2.waitKey(0)

运行结果:

2.Scharr 算子(增强版 Sobel)

Scharr 算子是 Sobel 算子的改进版本,使用更大的卷积核(3×3),对边缘的检测精度更高,尤其适合高分辨率图像或需要精细边缘的场景。

代码如下:

python 复制代码
zl = cv2.imread(r"C:\Users\LEGION\Desktop\OIP-C.webp",cv2.IMREAD_GRAYSCALE)
zl_x_64 = cv2.Scharr(zl,cv2.CV_64F,dx=1,dy=0)#默tilint8改为float64,可保存负数
zl_x_full =cv2.convertScaleAbs(zl_x_64)#转换为绝对值,负数转换为正数
zl_y_64 = cv2.Scharr(zl,cv2.CV_64F,dx=0,dy=1)#默t认int8改为float64,可保存负数
zl_y_full= cv2.convertScaleAbs(zl_y_64)#转换为绝对值,负数转换为正数
zl_xy_Scharr_full = cv2.addWeighted(zl_x_full, 1,zl_y_full,1,0)
cv2.imshow('zl_xy_Scharr_full',zl_xy_Scharr_full)
cv2.waitKey(0)

运行结果:

3.Laplacian 算子(二阶导数边缘检测)

Laplacian 算子基于二阶导数(梯度的变化率)检测边缘,无需分别计算 X/Y 方向,直接输出整体边缘。但它对噪声非常敏感,通常需要先进行高斯平滑处理。

代码如下:

python 复制代码
zl= cv2.imread(r"C:\Users\LEGION\Desktop\OIP-C.webp",cv2.IMREAD_GRAYSCALE)
zl_lap = cv2.Laplacian(zl,cv2.CV_64F,ksize=3)
zl_lap_full= cv2.convertScaleAbs(zl_lap)#转换为绝对值,负数转换为正数
cv2.imshow('zl_lap_full',zl_lap_full)
cv2.waitKey(0)

注意:ksize:卷积核大小,必须为奇数

运行结果:

4.Canny 算子(最优边缘检测)

Canny 算子是目前最优秀的边缘检测算法之一,融合了高斯平滑、非极大值抑制、双阈值筛选等步骤,能有效剔除伪边缘,得到连续、清晰的边缘轮廓。

代码如下:

python 复制代码
zl = cv2.imread(r"C:\Users\LEGION\Desktop\OIP-C.webp",cv2.IMREAD_GRAYSCALE)
cv2.imshow('zl',zl)
cv2.waitKey(0)
zl_canny = cv2.Canny(zl,  300, 150)#/低, 高
cv2.imshow(  'zl_canny',zl_canny)
cv2.waitKey(0)

参数说明:

src(灰度图), threshold1(低阈值), threshold2(高阈值)

原理:高于高阈值的为强边缘,低于低阈值的剔除,中间的仅当与强边缘相连时保留

注意:低阈值在前,高阈值在后

运行结果:

(左边为原灰度图,右边为处理后的图)

Canny 阈值选择技巧

  • 低阈值(threshold1):控制边缘的 "密度",值越小,检测到的边缘越多(包括噪声);
  • 高阈值(threshold2):控制边缘的 "精度",值越大,只有最明显的边缘会被保留;
  • 经验值:高阈值通常是低阈值的 2~3 倍,可根据图像实际效果调整。

四、四种边缘检测算法对比

  • 优先选 Canny:如果追求边缘质量和精度,且不特别在意计算速度。

  • 优先选 Sobel:如果需要实时性和低计算成本。

  • 优先选 Scharr:如果需要比 Sobel 更好的精度,且能接受稍高的计算量。

  • 谨慎用 Laplacian:必须配合高斯模糊预处理,否则噪声会严重影响结果。

相关推荐
STLearner2 小时前
MM 2025 | 时间序列(Time Series)论文总结【预测,分类,异常检测,医疗时序】
论文阅读·人工智能·深度学习·神经网络·算法·机器学习·数据挖掘
春日见2 小时前
Git 相关操作大全
linux·人工智能·驱动开发·git·算法·机器学习
Kingfar_12 小时前
高速列车驾驶员情境意识动态建模及生理反应机制研究
人工智能·机器学习
小二·2 小时前
Python Web 开发进阶实战:AI 原生硬件接口 —— 在 Flask + MicroPython 中构建边缘智能设备控制平台
前端·人工智能·python
TTGGGFF2 小时前
深度实战:在 GPU 环境下一键部署 Jimeng 中文文生图交互系统
人工智能·交互·图片生成
集和诚JHCTECH2 小时前
精准采摘背后的大脑:BRAV-7135边缘计算解决方案赋能智能农业新时代
人工智能·嵌入式硬件
deephub2 小时前
用 PydanticAI 让 LLM 输出变成可信赖的 Python 对象
人工智能·python·大语言模型·agent
cooldream20092 小时前
从辩论训练到具身智能——辩核AI具身辩论数字人系统整体设计思路
人工智能·具身数字人
Light602 小时前
智能融合,赋能未来:业财一体化与RPA的深度交响
人工智能·数字化转型·业财一体化·流程再造·机器人流程自动化·智能财务