深度学习之 OpenCV 图像边缘检测算法解析及代码演示

引言

在计算机视觉领域,边缘检测是一种重要的图像预处理技术,用于识别图像中对象的边界。边缘检测有助于提取图像的关键特征,这对于后续的图像分析(如物体识别、运动检测等)至关重要。OpenCV 是一个强大的计算机视觉库,提供了多种边缘检测算法。本文将重点介绍如何使用 OpenCV 进行图像边缘检测,并通过具体的代码示例来展示 Sobel 算子的应用。

Sobel 算子原理

Sobel 算子是一种广泛使用的边缘检测方法,它利用两个 3x3 的卷积核来分别计算图像在水平方向(x 方向)和垂直方向(y 方向)上的梯度。这两个卷积核如下所示:

  • 水平方向(x 方向)梯度核

  • 垂直方向(y 方向)梯度核

通过这两个核对图像进行卷积操作,可以获得图像在各个方向上的梯度信息,进而识别出图像中的边缘。

代码演示
  1. 导入库和读取图像

    1import cv2
    2
    3yuan = cv2.imread('yuan.png')
    4cv2.imshow('原图', yuan)
    5cv2.waitKey(0)

    解释:

    • 导入 cv2 库。
    • 使用 cv2.imread 函数读取名为 yuan.png 的图像文件。
    • 显示原始图像,并等待用户按键继续。
  2. x 方向上的边缘

    1# x方向上的边缘
    2yuan_x = cv2.Sobel(yuan, -1, dx=1, dy=0)
    3cv2.imshow('x方向边缘', yuan_x)
    4cv2.waitKey(0)

    解释:

    • 使用 cv2.Sobel 函数计算 x 方向上的边缘。
    • dx=1 表示在 x 方向上求一阶导数,dy=0 表示在 y 方向上保持不变。
    • 显示 x 方向上的边缘图像,并等待用户按键继续。
  3. x 方向上的边缘(包括负数信息)

    1# x方向上的边缘,包括负数信息(右端),但显示不出来,因为范围是(0~255)
    2yuan_x_64 = cv2.Sobel(yuan, cv2.CV_64F, dx=1, dy=0)  # 默认 uint8 改为 float64,可保存负数
    3cv2.imshow('x方向边缘(浮点型)', yuan_x_64)
    4cv2.waitKey(0)

    解释:

    • 将数据类型改为 cv2.CV_64F 以便保存负数。
    • 显示 x 方向上的边缘图像,但由于数据类型为浮点型,直接显示可能看不到清晰的边缘。
  4. x 方向上的边缘(包括负数信息,取绝对值)

    1# x方向上的边缘,包括负数信息,进行取绝对值的操作,右端的负值信息就可以显示出来了
    2yuan_x_full = cv2.convertScaleAbs(yuan_x_64)  # 转换为绝对值,负数转换为正数
    3cv2.imshow('x方向边缘(绝对值)', yuan_x_full)
    4cv2.waitKey(0)

    解释:

    • 使用 cv2.convertScaleAbs 函数将浮点型数据转换为整数型数据,并取绝对值。
    • 显示 x 方向上的边缘图像,此时可以看到清晰的边缘。
  5. y 方向上的边缘

    1# y方向上的边缘
    2yuan_y = cv2.Sobel(yuan, -1, dx=0, dy=1)
    3cv2.imshow('y方向边缘', yuan_y)
    4cv2.waitKey(0)

    解释:

    • 使用 cv2.Sobel 函数计算 y 方向上的边缘。
    • dx=0 表示在 x 方向上保持不变,dy=1 表示在 y 方向上求一阶导数。
    • 显示 y 方向上的边缘图像,并等待用户按键继续。
  6. y 方向上的边缘(包括负数信息,取绝对值)

    1# y方向上的边缘,包括负数信息(下端),但显示不出来,因为范围是(0~255)
    2yuan_y_64 = cv2.Sobel(yuan, cv2.CV_64F, dx=0, dy=1)  # 默认 int8 改为 float64,可保存负数
    3yuan_y_full = cv2.convertScaleAbs(yuan_y_64)  # 转换为绝对值,负数转换为正数
    4cv2.imshow('y方向边缘(绝对值)', yuan_y_full)
    5cv2.waitKey(0)

    解释:

    • 将数据类型改为 cv2.CV_64F 以便保存负数。
    • 使用 cv2.convertScaleAbs 函数将浮点型数据转换为整数型数据,并取绝对值。
    • 显示 y 方向上的边缘图像,此时可以看到清晰的边缘。
  7. 同时使用 x 和 y 方向的结果

    1# 如果同时使用 x,y 方向的结果如何呢?(不建议使用)
    2yuan_xy = cv2.Sobel(yuan, -1, dx=1, dy=1)
    3cv2.imshow('xy方向边缘', yuan_xy)
    4cv2.waitKey(100000)

    解释:

    • 使用 cv2.Sobel 函数计算 x 和 y 方向上的边缘。
    • dx=1 表示在 x 方向上求一阶导数,dy=1 表示在 y 方向上也求一阶导数。
    • 显示 xy 方向上的边缘图像,并等待用户按键继续。
  8. 使用图像加权运算组合 x 和 y 方向的 2 个边缘

    1# 使用图像加权运算组合 x 和 y 方向的 2 个边缘
    2yuan_xy_full = cv2.addWeighted(yuan_x_full, 1, yuan_y_full, 1, 0)
    3cv2.imshow('xy方向边缘(加权组合)', yuan_xy_full)
    4cv2.waitKey(0)

    解释:

    • 使用 cv2.addWeighted 函数将 x 方向和 y 方向的边缘图像进行加权组合。
    • 显示组合后的边缘图像,并等待用户按键继续。
输出结果:

总结

通过以上代码演示,我们展示了如何使用 OpenCV 的 Sobel 算子进行图像边缘检测。Sobel 算子通过计算图像在 x 和 y 方向上的梯度,能够有效地识别出图像中的边缘。此外,通过调整数据类型和使用绝对值转换,我们能够更好地显示边缘信息。这种边缘检测技术在许多计算机视觉应用中都有重要作用,如物体识别、运动检测等。

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值