计算机视觉--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:必须配合高斯模糊预处理,否则噪声会严重影响结果。

相关推荐
NAGNIP1 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab2 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab2 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP6 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年6 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼6 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS6 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区8 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈8 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang8 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx