OpenCV-高通滤波与边缘检测

本文介绍了高通滤波在图像处理中的应用,重点讨论了Sobel、Scharr、Laplacian和Canny边缘检测算子的原理、API示例及特点,强调了它们在边缘强调、噪声抑制和特征提取中的作用。
摘要由CSDN通过智能技术生成

所有相关接口验证demo以上传至仓库

代码地址:https://gitee.com/norep/learn-opencv

高通滤波

与低通滤波器效果相比,高通滤波器相反,它强调高频信号,如图像的细节和边缘,同时抑制低频信号。常见的实现方法包括梯度滤波器、拉普拉斯滤波器和双边滤波器(在某些情况下)。

高通滤波可以增强图像的边缘和细节,使图像看起来更清晰,但也可能放大噪声。

适用于图像锐化、边缘检测和特征提取,特别是在需要突出图像中的重要结构时。

在实际应用中,高通滤波和低通滤波经常结合使用,以达到特定的图像处理目标。例如,可以先用低通滤波器平滑图像以减少噪声,然后用高通滤波器增强边缘,从而在去噪的同时保留重要的视觉特征。

高通滤波器常用于边缘检测

边缘检测通常使用灰度图运算

边缘检测的主要评价标准

  • 低错误率:标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报。

  • 高定位性:标识出的边缘要与图像中的实际边缘尽可能接近。

  • 最小响应:图像中的边缘只能标识一次

索贝尔(Sobel)算子

边缘是像素值发生跃迁的位置

sobel算子对图像球一阶导数,一阶导数越大,说明像素在这个方向的变化越大,边缘信号越强。

因为图像是二维的,因此需要沿着宽与高两个方向的卷积核对原图进行处理。

#创建3x3的卷积核,指定卷积核的大小与权重,比如Sober滤波器,用于边缘检测
kernel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=np.float32)
kernel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]], dtype=np.float32)

这里只做举例,sobel算子有专用的api进行运算,无需手动生成卷积核。

API

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

参数说明:

  • src:一个 NumPy 数组,表示要进行 Sobel 滤波的源图像。这个图像应该是一个灰度图像。

  • ddepth:一个整数,表示输出图像的深度。这个值通常设置为 -1,表示输出图像的深度与源图像相同。

  • dx 和 dy:两个整数,分别表示在 x 方向和 y 方向上的差分阶数。通常,dx 和 dy 的值都是 1 或 2。

  • ksize:一个整数,表示 Sobel 滤波器的尺寸。这个值决定了滤波器的宽度,通常设置为 1、3 或 5。

  • borderType:(可选参数)一个整数,表示边界类型。常见的边界类型包括 cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE 等。

返回值:

  • dst:一个 NumPy 数组,表示 Sobel 滤波处理后的结果图像。

注意: 必须分开计算X轴与Y轴

举例

# sobel算子必须分开计算x轴与y轴
# sobel算子计算x轴梯度, 只有垂直方向的边缘
dx = cv2.Sobel(pic1, -1, dx = 1, dy = 0, ksize = 3)
# sobel算子计算y轴梯度, 只有水平方向的边缘
dy = cv2.Sobel(pic1, -1, dx = 0, dy = 1, ksize = 3)
# 合并图像
img = cv2.addWeighted(dx, 0.5, dy, 0.5, 0)

如下结果分别为,原图,x方向边缘,y方向边缘,合并后的图像。
在这里插入图片描述

沙尔(Scharr)

Scharr 滤波器是一种特殊的 Sobel 滤波器,它使用不同的系数来计算 x 方向和 y 方向的梯度。Sharr算子仅使用大小为3的卷积核,运算方法与Sober一样,但版Sober精准。

API

dst = cv2.Scharr(src, ddepth, dx, dy, borderType)

参数说明:

  • src:一个 NumPy 数组,表示要进行 Scharr 滤波的源图像。这个图像应该是一个灰度图像。

  • ddepth:一个整数,表示输出图像的深度。这个值通常设置为 -1,表示输出图像的深度与源图像相同。

  • dx 和 dy:两个整数,分别表示在 x 方向和 y 方向上的差分阶数。通常,dx 和 dy 的值都是 1。

  • borderType:(可选),一个整数,表示边界类型。常见的边界类型包括 cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE 等。

返回值:

  • dst:一个 NumPy 数组,表示 Scharr 滤波处理后的结果图像。

注意: Sharr算子与Sober算子一样,都需要分开计算X与Y方向。

示例

# Scharr算子必须分开计算x轴与y轴
# Scharr算子计算x轴梯度, 只有垂直方向的边缘
dx = cv2.Scharr(pic1, -1, dx = 1, dy = 0)
# Scharr算子计算y轴梯度, 只有水平方向的边缘
dy = cv2.Scharr(pic1, -1, dx = 0, dy = 1)
# 合并图像
img = cv2.addWeighted(dx, 0.5, dy, 0.5, 0)

如下结果分别为,原图,x方向边缘,y方向边缘,合并后的图像。
在这里插入图片描述

拉普拉斯算子(Laplacian)

拉普拉斯算子是一种二阶导数算子,用于检测图像中的亮度变化,从而找到边缘。

Sober算子模拟了一阶求导,导数越大的地方,说明变换越剧烈,越有可能是边缘
在这里插入图片描述
对上面的一维图像求导,可以得到导数最大的地方就可能是边缘
在这里插入图片描述
对上面的一阶导数图像再次求导,可以得知,图像边缘在二阶导数为0的地方。
在这里插入图片描述

拉普拉斯算子推导过程

在这里插入图片描述

API

拉普拉斯算子与Sobel和Scharr不同,拉普拉斯算子可以同时计算X方向与Y方向的边缘。

dst = cv2.Laplacian(src, ddepth, ksize=1, scale=1, delta=0, borderType=cv2.BORDER_DEFAULT)
# img = cv2.Laplacian(pic1, -1, ksize=3)

参数说明:

  • src:一个 NumPy 数组,表示要进行拉普拉斯边缘检测的源图像。这个图像应该是一个灰度图像。

  • ddepth:一个整数,表示输出图像的深度。这个值通常设置为 -1,表示输出图像的深度与源图像相同。

  • ksize:一个整数,表示拉普拉斯算子的核大小。通常设置为 1(对数组元素的直接邻居求导数),但也可以设置为更大的值(例如 3 或 5)来平滑结果。

  • scale:(可选)一个可选的浮点数,用于缩放输出图像。默认值为 1。

  • delta:(可选)一个可选的浮点数,用于对输出图像的每个像素值添加一个常数。默认值为 0。

  • borderType:(可选)一个整数,表示边界类型。常见的边界类型包括 cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE 等。

返回值:

  • dst:一个 NumPy 数组,表示拉普拉斯边缘检测处理后的结果图像

示例


# 拉普拉斯算子
img = cv2.Laplacian(pic1, -1, ksize=3)

cv2.namedWindow(windowName, cv2.WINDOW_NORMAL)
cv2.resizeWindow(windowName, 500 * 2, 500)
cv2.imshow(windowName, np.hstack((pic1, img)))

在这里插入图片描述

Canny

Canny 边缘检测器是一种流行的边缘检测方法,它通过使用高斯滤波器来平滑图像,然后使用梯度算子来计算图像的梯度,最后通过非极大值抑制(Non-Maximum Suppression)和双阈值检测来确定边缘。

Canny算子的实现边缘检测的一般步骤

去噪

边缘检测容易受到噪声干扰,一般使用高斯滤波去除噪声。

计算梯度

对平滑后的图像使用Sober算子计算梯度和方向
梯度方向一般归为4类,垂直、水平以及两个对角方向。
计算出的结果包含梯度与方向,一般如下图:
在这里插入图片描述

非极大值移植(NMS)

获取梯度与方向后,遍历图像,去除不是边界的点。
实现方法
逐个遍历像素点,判断当前像素是不是周围具有同方向梯度的最大值,
如下图中,判断点A是否是A、B、C中的局部最大值,如果是,则保留该点,否则他被归零。
在这里插入图片描述

滞后阈值

设置maxVal与minVal

大于macVal的值为边界,小于minVal的像素非边界则抛弃。

处于maxVal与minVal之间的像素,判断是否与边缘相连,如果是则保留,否则抛弃。
在这里插入图片描述

API

edges = cv2.Canny(image, threshold1, threshold2, apertureSize=3, L2gradient=False)

参数说明:

  • image:一个 NumPy 数组,表示要进行边缘检测的源图像。这个图像应该是一个灰度图像。

  • threshold1 和 threshold2:两个浮点数,分别表示边缘检测的两个阈值。较低的阈值用于边缘的低强度部分,较高的阈值用于边缘的高强度部分。

  • apertureSize:一个可选的整数,表示 Sobel 梯度算子的孔径大小。默认值为 3。

  • L2gradient:一个可选的布尔值,指示是否使用 L2norm 而不是 L1norm 来计算梯度的大小。默认值为 False。

返回值:

  • edges:一个 NumPy 数组,表示 Canny 边缘检测处理后的结果图像。

示例


# Canny算子
img = cv2.Canny(pic1, 71, 85)
cv2.imshow(windowName, img)

在这里插入图片描述

各滤波算法的特点与作用

算子特性
索贝尔(Sober)必须分开计算X轴与Y轴,图像梯度变化不大时,找不出边缘,存在明显误差
沙尔(Scharr)必须分开计算X轴与Y轴,寻找边缘比Sober更精准,对细小的边缘更敏感。
拉普拉斯(Laplacian)同时计算X轴与Y轴方向的边缘,效果比Sober和Scharr好,对噪声比较敏感。
Canny很多人认为是边缘检测的最优算法
  • 68
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌新程序猿~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值