1886 字
9 分钟
OpenCV:空域滤波【边缘检测】

1. 边缘检测#

1.1 基本概念#

​ 边缘检测的目的是 标识图像中亮度变换明显 的点。边缘检测大幅度的减少了图像的数据量,剔除了不相关的信息,保留了重要的结构属性图像的边缘检测是图像分割目标区域识别区域形状提取等图像分析的基石,也是图像中特征提取的很重要的方法

1.2 特征#

  • 沿着边缘方向,像素值逐渐平稳
  • 垂直于边缘方向,像素值变化剧烈

1.3 分类#

  • 阶跃性边缘两边的像素值有明显的差距一阶方向导数在边缘处是
  • 屋顶状边缘从增加到减少的转折点二阶方向导数在此处取得极值

2. 梯度计算#

​ 图像梯度计算的是图像变化的速度。对于图像的边缘部分,其灰度值变化较大,梯度值也较大,相反,对于图像中比较平滑的部分,其灰度值变化较小,相应的梯度值也较小。

2.1 一阶微分边缘检测#

​ 通过计算图像的梯度值来检测图像边缘,常见的算子有SobelPrewittRobertsCanny 等。

一阶导数可以产生 比较粗劣的边缘

2.2 二阶微分边缘检测#

​ 通过求二阶导数过零点来检测图像边缘,常见的算子有 LaplacianGauss-Laplacian等。

二阶导数对细节的把控比较好,如细线孤立的亮点等,但二阶导数在灰度斜坡和台阶出会产生双边边缘响应

3. Sobel算子#

3.1 滤波器#

水平方向垂直方向
水平方向垂直方向

3.2 使用方式#

  • 通过函数cv2.Sobel()实现Sobel算子运算
  • 函数原型dst = cv2.Sobel( src, ddepth, dx, dy, ksize, scale, delta, borderType )
  • 参数说明
    • dst:表示目标图像
    • src:表示原始图像
    • ddepth:表示处理结果图像的图像深度。通常设置为cv2.CV_64F
      • 如果直接将ddepth的值设置为-1,在计算时得到的结果可能是错误的
      • 在实际操作中,计算梯度值可能会出现负数。如果处理的图像是 8 位图类型, 则在ddepth的值为-1时,所有负数会自动截断为0,发生信息丢失
      • 为了避免信息丢失,在计算时要先使用更高的数据类型cv2.CV_64F,再通过取绝对值将其映射为cv2.CV_8U
    • dxdy:分别代表x方向上、y方向上的求导阶数。通常为0或者为1,最大值为2。
    • ksize:表示滤波核的大小。值为**-1时,会使用Scharr算子**进行运算。
    • scale:表示计算导数值时所采用的缩放因子,默认情况下是1,即没有缩放。
    • delta:表示额外加在目标图像上的值,默认为0。
    • borderType:表示边界样式,决定了以何种方式处理边界。
  • 边缘检测方向组合
xy检测方向
00不允许
01垂直方向检测:检测横线
10水平方向检测:检测竖线
11垂直方向检测 + 水平方向检测:检测角点

3.3 示例#

import cv2
src = cv2.imread("sample.png", cv2.IMREAD_GRAYSCALE)
SobelX = cv2.Sobel(src, cv2.CV_64F, 1, 0)
SobelX = cv2.convertScaleAbs(SobelX)
cv2.imwrite("sobel_x.png", SobelX)
SobelY = cv2.Sobel(src, cv2.CV_64F, 0, 1)
SobelY = cv2.convertScaleAbs(SobelY)
cv2.imwrite("sobel_y.png", SobelY)
SobelXY = cv2.Sobel(src, cv2.CV_64F, 1, 1)
SobelXY = cv2.convertScaleAbs(SobelXY)
cv2.imwrite("sobel_xy.png", SobelXY)
SobelXY = cv2.addWeighted(SobelX, 0.5, SobelY, 0.5, 0)
cv2.imwrite("sobel_x_y.png", SobelXY)
原图检测:横线检测:竖线检测:角点检测:横线+竖线
原图横线竖线角点横线+竖线

4. Scharr算子#

​ 在使用 3×3 的 Sobel 算子时,可能计算结果并不太精准。 Scharr 算子具有和Sobel算子同样的速度,且精度更高

4.1 滤波器#

水平方向垂直方向
水平方向垂直方向

4.2 使用方式#

  • 通过函数cv2.Scharr()实现Scharr算子运算
  • 函数原型dst = cv2.Scharr( src, ddepth, dx, dy, scale, delta, borderType )
  • 参数说明
    • dst:表示目标图像
    • src:表示原始图像
    • ddepth:表示处理结果图像的图像深度。通常设置为cv2.CV_64F
    • dxdy:分别代表x方向上、y方向上的求导阶数。通常为0或者为1,最大值为2。
    • scale:表示计算导数值时所采用的缩放因子,默认情况下是1,即没有缩放。
    • delta:表示额外加在目标图像上的值,默认为0。
    • borderType:表示边界样式,决定了以何种方式处理边界。
  • 边缘检测方向组合
xy检测方向
00不允许
01垂直方向检测:检测横线
10水平方向检测:检测竖线
11不允许

4.3 示例#

import cv2
src = cv2.imread("sample.png", cv2.IMREAD_GRAYSCALE)
ScharrX = cv2.Scharr(src, cv2.CV_64F, 1, 0)
ScharrX = cv2.convertScaleAbs(ScharrX)
cv2.imwrite("scharr_x.png", ScharrX)
ScharrY = cv2.Sobel(src, cv2.CV_64F, 0, 1)
ScharrY = cv2.convertScaleAbs(ScharrY)
cv2.imwrite("scharr_y.png", ScharrY)
ScharrXY = cv2.addWeighted(ScharrX, 0.5, ScharrY, 0.5, 0)
cv2.imwrite("scharr_x_y.png", ScharrXY)
原图检测:横线检测:竖线检测:横线+竖线
原图横线竖线横线+竖线

5. Canny算子#

​ Canny边缘检测是一种使用多级边缘检测算法检测边缘的方法。

5.1 原理及步骤#

  1. 去噪:噪声会影响边缘检测的准确性。
  • 通常采用高斯滤波去除图像中的噪声。
  1. 计算梯度的幅度与方向
  2. 非极大值抑制:适当地让边缘“变瘦”。
  • 根据梯度的幅度和方向,遍历图像中的像素点,去除所有非边缘的点
  1. 确定边缘:使用双阈值算法确定最终的边缘信息。
  • 设置两个阈值:高阈值 maxVal,低阈值 minVal。
  • 当前边缘像素的梯度值 ≥ maxVal, 则将当前边缘像素标记为强边缘
  • 当前边缘像素的梯度值介于maxVal与minVal之间,则将当前边缘像素标记为虚边缘
    • 与强边缘连接,则将该边缘处理为边缘
    • 与强边缘无连接,则该边缘为弱边缘,将其抑制
  • 当前边缘像素的梯度值 ≤ minVal,则抑制当前边缘像素。

5.2 使用方式#

  • 通过函数cv2.Canny()实现Canny算子运算
  • 函数原型dst = cv2.Canny( src, threshold1, threshold2, apertureSize, L2gradient )
  • 参数说明
    • dst:表示目标图像
    • src:表示原始图像
    • threshold1threshold2:分别表示Canny算子的低阈值高阈值
      • 值较小时,能够捕获更多的边缘信息
    • apertureSize:表示Sobel梯度计算的孔径大小
    • L2gradient :表示计算图像梯度幅度的标识,默认值为False

L2gradient

5.3 示例#

import cv2
src = cv2.imread("sample.png", cv2.IMREAD_GRAYSCALE)
dst = cv2.Canny(src, 128, 200)
cv2.imwrite("canny.png", dst)
原图Canny算子检测
原图Canny算子检测

6. Laplacian算子#

​ Laplacian算子是一种二阶导数算子, 具有旋转不变性, 可以满足不同方向的图像边缘检测的要求。通常情况下,Laplacian算子的系数之和需要为零

6.1 滤波器#

Laplacian边缘检测滤波器

6.2 使用方式#

  • 通过函数cv2.Laplacian()实现Laplacian算子运算
  • 函数原型dst = cv2.Laplacian( src, ddepth, ksize, scale, delta, borderType )
  • 参数说明
    • dst:表示目标图像
    • src:表示原始图像
    • ddepth:表示处理结果图像的图像深度。通常设置为cv2.CV_64F
    • ksize:表示滤波核的大小。必须是正奇数
    • scale:表示计算导数值时所采用的缩放因子,默认情况下是1,即没有缩放。
    • delta:表示额外加在目标图像上的值,默认为0。
    • borderType:表示边界样式,决定了以何种方式处理边界。

6.3 示例#

import cv2
src = cv2.imread("sample.png", cv2.IMREAD_GRAYSCALE)
Laplacian = cv2.Laplacian(src, cv2.CV_64F)
dst = cv2.convertScaleAbs(Laplacian)
cv2.imwrite("laplacian.png", dst)
原图Laplacian算子检测
原图Laplacian算子检测
封面
示例歌曲
示例艺术家
封面
示例歌曲
示例艺术家
0:00 / 0:00