机器学习:opencv--图像边缘检测

目录

前言

一、图像边缘检测

1.边缘检测

2.边缘检测的方法

二、Sobel算子

1.Sobel算子

2.计算

3.代码实现

4.代码步骤解析

1.导入图片

2.处理x轴和y轴的边缘并相加

三、Scharr算子

1.Scharr算子

2.计算

3.代码实现

四、Laplacian算子

1.Laplacian算子

2.计算

3.代码实现

五、Canny边缘检测算法

1.Canny

2.计算

3.代码实现

总结


前言

本篇将介绍图像边缘检测的Sobel、Scharr和Laplacian算子以及Canny边缘检测算法及其效果。

一、图像边缘检测

1.边缘检测

是图形图像处理、计算机视觉和机器视觉中的一个基本工具,通常用于特征提取和特征检测,旨在检测一张数字图像中有明显变化的边缘或者不连续的区域。

2.边缘检测的方法

二、Sobel算子

1.Sobel算子

Sobel 算子是一种离散的微分算子,该算子结合了高斯平滑和微分求导运算。该算子利用局部差分寻找边缘,计算所得的是一个梯度的近似值。

2.计算

计算过程简单的来说就是x轴放箱费和y轴方向各一个矩阵,对图像的所有像素点做卷积操作寻找梯度

3.代码实现

完整代码:

python 复制代码
import cv2

"""Sobel算子"""
yuan = cv2.imread('../yuan.png')
cv2.imshow('yuan', yuan)
cv2.waitKey(0)

'''x方向上的边缘'''
# 右端为负值 显示不出来
yuan_x_64 = cv2.Sobel(yuan, cv2.CV_64F, dx=1, dy=0)
cv2.imshow('yuan_x_64', yuan_x_64)
cv2.waitKey(0)

# 进行取绝对值操作即可
yuan_x_full = cv2.convertScaleAbs(yuan_x_64)
cv2.imshow('yuan_x_full', yuan_x_full)
cv2.waitKey(0)

'''y方向上的边缘'''
# y的下端为负值 显示不出来
# 进行取绝对值操作即可
yuan_y_64 = cv2.Sobel(yuan, cv2.CV_64F, dx=0, dy=1)
yuan_y_full = cv2.convertScaleAbs(yuan_y_64)
cv2.imshow('yuan_y_full', yuan_y_full)
cv2.waitKey(0)

'''使用加权运算组合图像得到完整边缘'''
yuan_xy_full = cv2.addWeighted(yuan_x_full, 1, yuan_y_full, 1, 10)
cv2.imshow('yuan_xy_full', yuan_xy_full)
cv2.waitKey(0)
cv2.destroyAllWindows()

"""使用彩色图获取边缘"""
zrn = cv2.imread('../zrn.jpg', cv2.IMREAD_GRAYSCALE)
zrn = cv2.resize(zrn, (400, 400))
x = cv2.Sobel(zrn, cv2.CV_64F, dx=1, dy=0)
y = cv2.Sobel(zrn, cv2.CV_64F, dx=0, dy=1)
x_full = cv2.convertScaleAbs(x)
y_full = cv2.convertScaleAbs(y)
xy = cv2.addWeighted(x_full, 1, y_full, 1, 0)
cv2.imshow('zrn_Sobel', xy)
cv2.waitKey(0)

输出:

4.代码步骤解析

1.导入图片

python 复制代码
import cv2

"""Sobel算子"""
yuan = cv2.imread('../yuan.png')
cv2.imshow('yuan', yuan)
cv2.waitKey(0)

2.处理x轴和y轴的边缘并相加

  • x轴:
python 复制代码
'''x方向上的边缘'''
# 右端为负值 显示不出来
yuan_x_64 = cv2.Sobel(yuan, cv2.CV_64F, dx=1, dy=0)
cv2.imshow('yuan_x_64', yuan_x_64)
cv2.waitKey(0)

# 进行取绝对值操作即可
yuan_x_full = cv2.convertScaleAbs(yuan_x_64)
cv2.imshow('yuan_x_full', yuan_x_full)
cv2.waitKey(0)

输出:

左边的右边边缘没显示出来是因为进行计算之后这些位置的像素值为负值,显示不出来。

经过取绝对值操作之后即可完整显示出来

  • 完整边缘:

y轴的处理与x轴一致

完整的边缘只需将两个轴上的数据进行加权相加即可

python 复制代码
'''y方向上的边缘'''
# y的下端为负值 显示不出来
# 进行取绝对值操作即可
yuan_y_64 = cv2.Sobel(yuan, cv2.CV_64F, dx=0, dy=1)
yuan_y_full = cv2.convertScaleAbs(yuan_y_64)
cv2.imshow('yuan_y_full', yuan_y_full)
cv2.waitKey(0)

'''使用加权运算组合图像得到完整边缘'''
yuan_xy_full = cv2.addWeighted(yuan_x_full, 1, yuan_y_full, 1, 10)
cv2.imshow('yuan_xy_full', yuan_xy_full)
cv2.waitKey(0)
cv2.destroyAllWindows()

最终结果:

三、Scharr算子

1.Scharr算子

Scharr 算子是 Soble 算子在 ksize=3 时的优化,与 Soble 的速度相同,且精度更高。Scharr 算子与 Sobel 算子的不同点是在平滑部分,其中心元素占的权重更重,相当于使用较小标准差的高斯函数,也就是更瘦高的模板。

2.计算

计算过程与sobel算子相同,只是所用矩阵有差别

3.代码实现

完整代码:

  • 实现步骤与Sobel的步骤一模一样,在此就不过多赘述了。
python 复制代码
import cv2

"""Scharr(xia)算子"""
zrn1 = cv2.imread('../zrn.jpg', cv2.IMREAD_GRAYSCALE)
zrn1 = cv2.resize(zrn1, (400, 400))
x = cv2.Scharr(zrn1, cv2.CV_64F, dx=1, dy=0)
y = cv2.Scharr(zrn1, cv2.CV_64F, dx=0, dy=1)
x_full = cv2.convertScaleAbs(x)
y_full = cv2.convertScaleAbs(y)
xy = cv2.addWeighted(x_full, 1, y_full, 1, 0)
cv2.imshow('zrn_Scharr', xy)
cv2.waitKey(0)

输出:

四、Laplacian算子

1.Laplacian算子

不再以x和y的方向计算,而是以圆方向计算变化率。因此不需要Gx+Gy。

2.计算

简单来说就是只使用一个矩阵去跟所有的点进行卷积,得到的结果直接作为边缘

3.代码实现

完整代码:

步骤就是将Sobelx轴和y轴的步骤合二为一,并将取绝对值和加权相加的步骤去除了

python 复制代码
import cv2

"""Laplacian算子"""
zrn1 = cv2.imread('zrn.jpg', cv2.IMREAD_GRAYSCALE)
zrn1 = cv2.resize(zrn1, (400, 400))
lap = cv2.Laplacian(zrn1, cv2.CV_64F, delta=10)
lap_full = cv2.convertScaleAbs(lap)
cv2.imshow('zrn_Lap', lap_full)
cv2.waitKey(0)

输出:

五、Canny边缘检测算法

1.Canny

Canny 边缘检测是一种图像处理技术,用于检测图像中的边缘。它通过以下几个步骤实现:首先对图像进行平滑处理以减少噪声;接着计算每个像素的梯度强度和方向;然后进行非极大值抑制以精确定位边缘;最后应用双阈值化和边缘连接来确定最终的边缘。这种方法能有效地识别和提取图像中的显著边缘。

2.计算

canny的计算分为四步

  1. 图像降噪
  2. 梯度计算
  3. 非极大值抑制
  4. 双阈值边界跟踪

具体内容感兴趣的可以搜索查看

3.代码实现

完整代码:

使用算法的代码就cv2.Canny()那一行,数字参数代表高低阈值,可以自己调试看看效果有何不同

python 复制代码
import cv2

"""Canny算子"""
suda = cv2.imread('suda.jpg', cv2.IMREAD_GRAYSCALE)
suda = cv2.resize(suda, (400, 400))
cv2.imshow('suda', suda)
cv2.waitKey(0)
can = cv2.Canny(suda, 100, 200)  # 低阈值 高阈值
cv2.imshow('suda_canny', can)
cv2.waitKey(0)

输出:

总结

这么多种算法各有千秋,面对每种情况可以选择适合的算法

相关推荐
普密斯科技18 分钟前
手机外观边框缺陷视觉检测智慧方案
人工智能·计算机视觉·智能手机·自动化·视觉检测·集成测试
四口鲸鱼爱吃盐30 分钟前
Pytorch | 利用AI-FGTM针对CIFAR10上的ResNet分类器进行对抗攻击
人工智能·pytorch·python
lishanlu13632 分钟前
Pytorch分布式训练
人工智能·ddp·pytorch并行训练
日出等日落1 小时前
从零开始使用MaxKB打造本地大语言模型智能问答系统与远程交互
人工智能·语言模型·自然语言处理
三木吧1 小时前
开发微信小程序的过程与心得
人工智能·微信小程序·小程序
whaosoft-1431 小时前
w~视觉~3D~合集5
人工智能
猫头虎1 小时前
新纪天工 开物焕彩:重大科技成就发布会参会感
人工智能·开源·aigc·开放原子·开源软件·gpu算力·agi
正在走向自律2 小时前
京东物流营销 Agent:智能驱动,物流新篇(13/30)
人工智能·ai agent·ai智能体·京东物流agent
远洋录3 小时前
React性能优化实战:从理论到落地的最佳实践
前端·人工智能·react
KD3353 小时前
Marscode AI辅助编程
人工智能