[Python从零到壹] 五十九.图像增强及运算篇之图像锐化Scharr、Canny、LOG实现边缘检测

举报
eastmount 发表于 2023/09/06 10:25:40 2023/09/06
【摘要】 欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。图像锐化和边缘检测主要包括一阶微分锐化和二阶微分锐化,本文主要讲解常见的图像锐化和边缘检测方法,即Scharr算子、Canny算子和LOG算子。希望文章对您有所帮助!

欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十年的编程经验分享给大家,希望对您有所帮助,文章中不足之处也请海涵。Python系列整体框架包括基础语法10篇、网络爬虫30篇、可视化分析10篇、机器学习20篇、大数据分析20篇、图像识别30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的关注、点赞和转发就是对秀璋最大的支持,知识无价人有情,希望我们都能在人生路上开心快乐、共同成长。

该系列文章主要讲解Python OpenCV图像处理和图像识别知识,前期主要讲解图像处理基础知识、OpenCV基础用法、常用图像绘制方法、图像几何变换等,中期讲解图像处理的各种运算,包括图像点运算、形态学处理、图像锐化、图像增强、图像平滑等,后期研究图像识别、图像分割、图像分类、图像特效处理以及图像处理相关应用。

第二部分将讲解图像运算和图像增强,上一篇文章介绍图像锐化的Sobel算子和Laplacian算子。这篇文章将继续讲解图像锐化知识。在图像收集和传输过程中,可能会受一些外界因素造成图像模糊和有噪声的情况,从而影响到后续的图像处理和识别。此时可以通过图像锐化和边缘检测,加强原图像的高频部分,锐化突出图像的边缘细节,改善图像的对比度,使模糊的图像变得更清晰。图像锐化和边缘检测主要包括一阶微分锐化和二阶微分锐化,本文主要讲解常见的图像锐化和边缘检测方法,即Scharr算子、Canny算子和LOG算子。希望文章对您有所帮助,如果有不足之处,还请海涵。

下载地址:记得点赞喔 O(∩_∩)O

前文赏析:

第一部分 基础语法

第二部分 网络爬虫

第三部分 数据分析和机器学习

  • [Python从零到壹] 十九.可视化分析之热力图和箱图绘制及应用详解
  • [Python从零到壹] 二十.可视化分析之Seaborn绘图万字详解
  • [Python从零到壹] 二十一.可视化分析之Pyechart绘图万字详解
  • [Python从零到壹] 二十二.可视化分析之OpenGL绘图万字详解
  • [Python从零到壹] 二十三.十大机器学习算法之决策树分类分析详解(1)
  • [Python从零到壹] 二十四.十大机器学习算法之KMeans聚类分析详解(2)
  • [Python从零到壹] 二十五.十大机器学习算法之KNN算法及图像分类详解(3)
  • [Python从零到壹] 二十六.十大机器学习算法之朴素贝叶斯算法及文本分类详解(4)
  • [Python从零到壹] 二十七.十大机器学习算法之线性回归算法分析详解(5)
  • [Python从零到壹] 二十八.十大机器学习算法之SVM算法分析详解(6)
  • [Python从零到壹] 二十九.十大机器学习算法之随机森林算法分析详解(7)
  • [Python从零到壹] 三十.十大机器学习算法之逻辑回归算法及恶意请求检测应用详解(8)
  • [Python从零到壹] 三十一.十大机器学习算法之Boosting和AdaBoost应用详解(9)
  • [Python从零到壹] 三十二.十大机器学习算法之层次聚类和树状图聚类应用详解(10)

第四部分 Python图像处理基础

第五部分 Python图像运算和图像增强

第六部分 Python图像识别和图像高阶案例

第七部分 NLP与文本挖掘

第八部分 人工智能入门知识

第九部分 网络攻防与AI安全

第十部分 知识图谱构建实战

扩展部分 人工智能高级案例


一.Scharr算子

由于Sobel算子在计算相对较小的核的时候,其近似计算导数的精度比较低,比如一个3×3的Sobel算子,当梯度角度接近水平或垂直方向时,其不精确性就越发明显。Scharr算子同Sobel算子的速度一样快,但是准确率更高,尤其是计算较小核的情景,所以利用3×3滤波器实现图像边缘提取更推荐使用Scharr算子。

Scharr算子又称为Scharr滤波器,也是计算x或y方向上的图像差分,在OpenCV中主要是配合Sobel算子的运算而存在的,其滤波器的滤波系数如下:

在这里插入图片描述

Scharr算子的函数原型如下所示,和Sobel算子几乎一致,只是没有ksize参数。

  • dst = Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]]])
    – src表示输入图像
    – dst表示输出的边缘图,其大小和通道数与输入图像相同
    – ddepth表示目标图像所需的深度,针对不同的输入图像,输出目标图像有不同的深度
    – dx表示x方向上的差分阶数,取值1或 0
    – dy表示y方向上的差分阶数,取值1或0
    – scale表示缩放导数的比例常数,默认情况下没有伸缩系数
    – delta表示将结果存入目标图像之前,添加到结果中的可选增量值
    – borderType表示边框模式,更多详细信息查阅BorderTypes

Scharr算子的实现代码如下所示。

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图像
img = cv2.imread('luo.png')
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

#灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
# Scharr算子
x = cv2.Scharr(grayImage, cv2.CV_32F, 1, 0) #X方向
y = cv2.Scharr(grayImage, cv2.CV_32F, 0, 1) #Y方向
absX = cv2.convertScaleAbs(x)       
absY = cv2.convertScaleAbs(y)
Scharr = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', 'Scharr算子']  
images = [lenna_img, Scharr]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()

其运行结果如图1所示:

在这里插入图片描述


二.Cann算子

John F.Canny于1986年发明了一个多级边缘检测算法——Canny边缘检测算子,并创立了边缘检测计算理论(Computational theory of edge detection),该理论有效地解释了这项技术的工作理论。

边缘检测通常是在保留原有图像属性的情况下,对图像数据规模进行缩减,提取图像边缘轮廓的处理方式。Canny算法是一种被广泛应用于边缘检测的标准算法,其目标是找到一个最优的边缘检测解或找寻一幅图像中灰度强度变化最强的位置。最优边缘检测主要通过低错误率、高定位性和最小响应三个标准进行评价。Canny算子的实现步骤如下:

第一步,使用高斯平滑(如公式2所示)去除噪声。

在这里插入图片描述

第二步,按照Sobel滤波器步骤计算梯度幅值和方向,寻找图像的强度梯度。先将卷积模板分别作用x和y方向,再计算梯度幅值和方向,其公式如下所示。梯度方向一般取0度、45度、90度和135度四个方向。

在这里插入图片描述
在这里插入图片描述

第三步,通过非极大值抑制(Non-maximum Suppression)过滤掉非边缘像素,将模糊的边界变得清晰。该过程保留了每个像素点上梯度强度的极大值,过滤掉其他的值。对于每个像素点,它进行如下操作:

  • 将其梯度方向近似为以下值中的一个,包括0、45、90、135、180、225、270和315,即表示上下左右和45度方向;
  • 比较该像素点和其梯度正负方向的像素点的梯度强度,如果该像素点梯度强度最大则保留,否则抑制(删除,即置为0)。其处理后效果如图2所示,左边表示梯度值,右边表示非极大值抑制处理后的边缘。

在这里插入图片描述

第四步,利用双阈值方法来确定潜在的边界。经过非极大抑制后图像中仍然有很多噪声点,此时需要通过双阈值技术处理,即设定一个阈值上界和阈值下界。图像中的像素点如果大于阈值上界则认为必然是边界(称为强边界,strong edge),小于阈值下界则认为必然不是边界,两者之间的则认为是候选项(称为弱边界,weak edge)。经过双阈值处理的图像如图3所示,左边为非极大值抑制处理后的边缘,右边为双阈值技术处理的效果图。

在这里插入图片描述

第五步,利用滞后技术来跟踪边界。若某一像素位置和强边界相连的弱边界认为是边界,其他的弱边界则被删除。
在OpenCV中,Canny()函数原型如下所示:

  • edges = Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
    – image表示输入图像
    – edges表示输出的边缘图,其大小和类型与输入图像相同
    – threshold1表示第一个滞后性阈值
    – threshold2表示第二个滞后性阈值
    – apertureSize表示应用Sobel算子的孔径大小,其默认值为3
    – L2gradient表示一个计算图像梯度幅值的标识,默认值为false

Canny算子的边缘提取实现代码如下所示:

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图像
img = cv2.imread('luo.png')
lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#高斯滤波降噪
gaussian = cv2.GaussianBlur(grayImage, (3,3), 0)
 
#Canny算子
Canny = cv2.Canny(gaussian, 50, 150) 

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', 'Canny算子']  
images = [lenna_img, Canny]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()

其运行结果如图4所示:

在这里插入图片描述


三.LOG算子

LOG(Laplacian of Gaussian)边缘检测算子是David Courtnay Marr和Ellen Hildreth在1980年共同提出的,也称为Marr & Hildreth算子,它根据图像的信噪比来求检测边缘的最优滤波器。该算法首先对图像做高斯滤波,然后再求其拉普拉斯(Laplacian)二阶导数,根据二阶导数的过零点来检测图像的边界,即通过检测滤波结果的零交叉(Zero crossings)来获得图像或物体的边缘。

LOG算子综合考虑了对噪声的抑制和对边缘的检测两个方面,并且把Gauss平滑滤波器和Laplacian锐化滤波器结合了起来,先平滑掉噪声,再进行边缘检测,所以效果会更好。 该算子与视觉生理中的数学模型相似,因此在图像处理领域中得到了广泛的应用。它具有抗干扰能力强,边界定位精度高,边缘连续性好,能有效提取对比度弱的边界等特点。

常见的LOG算子是5×5模板,如下所示:

在这里插入图片描述

由于LOG算子到中心的距离与位置加权系数的关系曲线像墨西哥草帽的剖面,所以LOG算子也叫墨西哥草帽滤波器,如图5所示。

在这里插入图片描述

LOG算子的边缘提取实现代码如下所示:

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
 
#读取图像
img = cv2.imread('luo.png')
lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#先通过高斯滤波降噪
gaussian = cv2.GaussianBlur(grayImage, (3,3), 0)
 
#再通过拉普拉斯算子做边缘检测
dst = cv2.Laplacian(gaussian, cv2.CV_16S, ksize = 3)
LOG = cv2.convertScaleAbs(dst)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', 'LOG算子']  
images = [lenna_img, LOG]  
for i in range(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()

其运行结果如图6所示:

在这里插入图片描述


四.总结

该系列文章主要通过Roberts算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr算子、Canny算子和LOG算子实现图像锐化和边缘检测,有效地提取了图像的轮廓,并进行了详细地实验处理。

感谢在求学路上的同行者,不负遇见,勿忘初心。作者在华为云社区开放了Python图像处理系列书籍,图像处理系列主要包括三部分,分别是:

在这里插入图片描述

在这里插入图片描述

请添加图片描述

感恩能与大家在华为云遇见!
希望能与大家一起在华为云社区共同成长,原文地址:https://blog.csdn.net/Eastmount/article/details/128397285
(By:Eastmount 2023-09-06 夜于贵州)


参考文献:

  • [1] 冈萨雷斯著,阮秋琦译. 数字图像处理(第3版)[M]. 北京:电子工业出版社,2013.
  • [2] 阮秋琦. 数字图像处理学(第3版)[M]. 北京:电子工业出版社,2008.
  • [3] 杨秀璋,于小民,范郁锋,李娜. 基于苗族服饰的图像锐化和边缘提取技术研究[J]. 现代计算机,2018-10.
  • [4] Eastmount. [Python图像处理] 四.图像平滑之均值滤波、方框滤波、高斯滤波及中值滤波[EB/OL]. (2018-09-02). https://blog.csdn.net/Eastmount/article/details/82216380.
  • [5] Eastmount. [数字图像处理] 七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解[EB/OL]. (2015-06-08). https://blog.csdn.net/eastmount/article/ details/46378783.
  • [6] DSQiu. 图像锐化(增强)和边缘检测[EB/OL]. (2012-08-20). https://dsqiu.iteye.com/blog/1638589.https://blog.csdn.net/poem_qianmo/article/details/23184547.
  • [7] C. Tomasi, R Manduchi. Bilateral Filtering for Gray and Color images[C]. Proceedings of the IEEE International Conference on Computer Vision, Bombay, India. 1998:839-846.
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。