一、边缘检测

1.sobel算子

cv2.Sobel() 是 OpenCV 实现索贝尔算子(Sobel Operator) 的函数,它通过计算图像的梯度来检测边缘。

cv2.Sobel(src, ddepth, dx, dy, ksize=None)

src :   输入图像(通常是灰度图)
ddepth:    输出图像的深度(推荐用 cv2.CV_64F,避免梯度为负时被截断)
dx  :  x 方向的导数阶数(0/1/2,边缘检测常用 1)
dy  :  y 方向的导数阶数(0/1/2,边缘检测常用 1)
ksize :   核的大小(奇数,如 3/5/7,默认 3;设为 -1 时用 Scharr 算子,效果更好)

代码:用x方向的导数阶数

yuan = cv2.imread('2_GRAY.jpg')
cv2.imshow('yuan',yuan)
cv2.waitKey(0)
##x方向上的边缘
yuan_x=cv2.Sobel(yuan,-1,dx=1,dy=0)
cv2.imshow('yuan_x',yuan_x)
cv2.waitKey(0)
#x方向上的边缘,包括负数信息(右端),但显示不出来,因为范围是(0~255)
yuan_x_64=cv2.Sobel(yuan,cv2.CV_64F,dx=1,dy=0)#默认uint8改为float64,可保存负数
cv2.imshow('yuan_x_64',yuan_x_64)
cv2.waitKey(0)
##x方向上的边缘,包括负数信息,进行取绝对值的操作,右端的负值信息就可以显示出来了
yuan_x_full=cv2.convertScaleAbs(yuan_x_64)#转换为给对值,负数转换为正数
cv2.imshow('yuan_x_full',yuan_x_full)
cv2.waitKey(0)

原图:

ddepth:输出图像的深度(可以理解为数据类型),-1表示与原图像相同的深度yuan_x=cv2.Sobel(yuan,-1,dx=1,dy=0)得到的图像

cv2.Sobel(yuan,cv2.CV_64F,dx=1,dy=0):cv2.CV_64F:因为梯度可能为负数(比如从亮到暗),用 64 位浮点型可以保留负数值,避免信息丢失得到的图像

cv2.convertScaleAbs(yuan_x_64):将负梯度值转为绝对值得到的图像

代码:用y方向的导数阶数

# #y方向上的边缘
yuan_y =cv2.Sobel(yuan,-1,dx=0,dy=1)
cv2.imshow('yuan_y',yuan_y)
cv2.waitKey(0)
#y方向上的边缘,包括负数信息(下端),但显示不出来,因为范围是(0~255)
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)

得到的图像:

2.Scharr 算子

Scharr 算子是对 Sobel 算子的优化版本,核心特点是:

  • 同样用于图像梯度(边缘)检测,原理和 Sobel 一致(计算 x/y 方向梯度);

  • 针对 3x3 核做了权重优化,梯度计算更精准,边缘检测结果更清晰;

  • 没有核大小的选择(固定 3x3),可以理解为 “高精度版 3x3 Sobel”。

zl =cv2.imread('2.png',cv2.IMREAD_GRAYSCALE)#Scharr_算子
# zl=cv2.cvtColor(zl,cv2.COLOR_BGR2GRAY)
zl_x_64=cv2.Scharr(zl,cv2.CV_64F,dx=1,dy=0)#默以int8改为float64,可保存负数
zl_x_full=cv2.convertScaleAbs(zl_x_64)#转换为绝对值.负数转换为正数
zl_y_64=cv2.Scharr(zl,cv2.CV_64F,dx=0,dy=1)#默以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)

与sobel算子的用法差不多,这里还用了cv2.addWeighted(zl_x_full,1,zl_y_full,1,0)方法加权合并两张图像( Scharr 算子的 x 方向边缘图和 y 方向边缘图),最终得到同时包含水平和垂直边缘的完整边缘图像。

3.Laplacian

        这是一种基于拉普拉斯算子的边缘检测方法,和之前讲的 Sobel/Scharr(一阶梯度)不同,它是二阶梯度算子,能直接检测出图像中所有方向的边缘

cv2.Laplacian(src, ddepth, ksize=1, scale=1,delta=0)

src:输入图像,可以是灰度图像,也可以是多通道的彩色图像
ddepth:输出图片的数据深度:
ksize:计算二阶导数滤波器的孔径大小,必须为正奇数,可选项
scale:缩放比例因子,可选项,默认值为1
delta:输出图像的偏移量,可选项,默认值为0

zl =cv2.imread('2.png',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)

得到的图像:

4.canny边缘检测

作用:它是一套完整的边缘检测流程,能得到更干净、更准确的边缘结果

Canny 检测的 4 个核心步骤

  1. 高斯模糊:先对图像去噪(解决噪声干扰边缘的问题);

  2. 计算梯度:用 Sobel 算子计算图像的梯度(幅度 + 方向),找到边缘候选点;

  3. 非极大值抑制:只保留梯度方向上的局部最大值(把宽边缘 “细化” 成单像素宽度);

  4. 双阈值筛选:用高低两个阈值过滤边缘 —— 高于高阈值的是确定边缘,低于低阈值的直接舍弃,介于两者之间的仅当和确定边缘相连时保留(大幅减少伪边缘)。

canny函数:cv2.Canny(image, threshold1, threshold2, apertureSize=3, L2gradient=False)

image:输入图像(灰度图最佳,彩色图也可但效率低)
threshold1:低阈值(通常设为高阈值的 1/2 或 1/3)
threshold2:高阈值(核心参数,需根据图像调整,常用 100-200)
apertureSize:计算梯度用的 Sobel 核大小(默认 3,奇数)
L2gradient:梯度计算方式:False(默认,L1 范数,速度快);True(L2 范数,精度高)

代码:

zl =cv2.imread('2.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow('zl',zl)
cv2.waitKey(0)
zl_canny=cv2.Canny(zl,100,150)#低,高
cv2.imshow('zl_canny',zl_canny)
cv2.waitKey(0)

得到的图像:

Logo

昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链

更多推荐