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

输出:

总结

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

相关推荐
我是瓦力9 分钟前
PointNet++改进策略 :模块改进 | EdgeConv | DGCNN, 动态图卷积在3d任务上应用
人工智能·深度学习·计算机视觉·3d
咔咔学姐kk24 分钟前
2024最新版,人大赵鑫老师《大语言模型》新书pdf分享
数据库·人工智能·语言模型·自然语言处理·pdf·知识图谱·产品经理
z千鑫32 分钟前
【人工智能】OpenAI发布GPT-o1模型:推理能力的革命性突破,这将再次刷新编程领域的格局!
人工智能·gpt·agent·ai编程·工作流·ai助手·ai工具
AIBox36534 分钟前
GPT撰写开题报告教程——课题确定及文献调研
人工智能·chatgpt
AIBigModel37 分钟前
关于GPT5训练失败的思考
人工智能·知识图谱
绎岚科技41 分钟前
深度学习自编码器 - 随机编码器和解码器篇
人工智能·深度学习·算法·机器学习
吃什么芹菜卷43 分钟前
2024.9最新:CUDA安装,pytorch库安装
人工智能·pytorch·笔记·python·深度学习
ymchuangke1 小时前
评价类——熵权法(Entropy Weight Method, EWM),完全客观评价
人工智能·python·算法·机器学习·数学建模
嵌入式杂谈1 小时前
人工智能在C/C++中的应用:图像处理与机器学习
c语言·c++·人工智能
十启树2 小时前
用Qt 对接‌百度语音识别接口
人工智能·qt·百度·语音识别