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

Posted Eastmount

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Python从零到壹] 五十九.图像增强及运算篇之图像锐化ScharrCannyLOG实现边缘检测相关的知识,希望对你有一定的参考价值。

欢迎大家来到“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图像运算和图像增强

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

第七部分 NLP与文本挖掘

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

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

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

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

作者新开的“娜璋AI安全之家”将专注于Python和安全技术,主要分享Web渗透、系统安全、人工智能、大数据分析、图像识别、恶意代码检测、CVE复现、威胁情报分析等文章。虽然作者是一名技术小白,但会保证每一篇文章都会很用心地撰写,希望这些基础性文章对你有所帮助,在Python和安全路上与大家一起进步。


一.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算子实现图像锐化和边缘检测,有效地提取了图像的轮廓,并进行了详细地实验处理。

感谢在求学路上的同行者,不负遇见,勿忘初心。图像处理系列主要包括三部分,分别是:

2022年即将离去,又是忙碌的一年,感谢女神的鼓励和小珞治愈的笑容。守得云开见明月,加油!读博四年,还是写了一些东西,从初入安全的无知到现在的懵懂,也记录一些笔记,也希望对大家有所帮助。思过崖一周难忘的经历,心情五味陈杂,忙忙碌碌,期间还赶了论文修改的DDL前晚收到家人的生日祝福很开心,一句话就很温暖。回想那晚带上了他俩的照片,亲情永远那么美好。希望小珞珞永远开心,全家人平平安安,身体健康,爱你们喔!2022年最重要的事活着,希望大家都好。

(By:Eastmount 2022-12-21 夜于武汉 http://blog.csdn.net/eastmount/ )


参考文献:

  • [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.

以上是关于[Python从零到壹] 五十九.图像增强及运算篇之图像锐化ScharrCannyLOG实现边缘检测的主要内容,如果未能解决你的问题,请参考以下文章

[Python从零到壹] 四十九.图像增强及运算篇之顶帽运算和底帽运算

[Python从零到壹] 四十九.图像增强及运算篇之顶帽运算和底帽运算

[Python从零到壹] 五十.图像增强及运算篇之图像直方图理论知识和绘制实现

[Python从零到壹] 五十.图像增强及运算篇之图像直方图理论知识和绘制实现

[Python从零到壹] 五十七.图像增强及运算篇之图像锐化RobertsPrewitt算子实现边缘检测

[Python从零到壹] 五十八.图像增强及运算篇之图像锐化SobelLaplacian算子实现边缘检测