机器学习: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)

输出:

总结

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

相关推荐
哈哈哈也不行吗6 小时前
用大角几何整理几何教研案例:从作图到复用的一个思路
人工智能·在线工具·几何绘图·大角几何
新知图书6 小时前
16.1 基于MCP的多Agent旅行规划助手系统概述
人工智能·agent·ai agent·智能体
u1301307 小时前
AI 日报(2026年8月29日)
人工智能
chunmiao30328 小时前
OpenAI 等 116 家机构联名发公开信:AI 网络攻击将进入高发期
人工智能
VALENIAN瓦伦尼安教学设备8 小时前
设备状态检测振动分析实训台案例分析
大数据·数据库·人工智能·嵌入式硬件·算法
Warren2Lynch8 小时前
面向对象设计中的 UML 类图指南
人工智能·uml
2601_966871408 小时前
周大都督2026年零基础手写大模型系统课
人工智能
hyuk的AI工坊8 小时前
向量数据库实战:LangChain4j 双后端向量检索(InMemory 持久化 + ChromaDB)
人工智能
INNOVIX稳石机器人8 小时前
稳石500强实战验证:从人工仓储迈向AI自主智造,给出仓储自动化升级标准答案
运维·人工智能·自动化