本文分享自华为云社区《【Python从零到一】五十八.图像增强与计算:图像锐化Sobel和拉普拉斯算子实现边缘检测》,作者:eastmount。
欢迎来到《Python从零到一》,这里我将分享约200篇Python系列文章,带你一起学、一起玩,看看Python的有趣世界。所有文章都会根据案例、代码和作者的经验进行解释。我真诚地想与大家分享我近十年的编程经验。希望对您有所帮助。文章中如有不足之处还请大家多多包涵。 Python系列整体框架包括基础语法10篇、网络爬虫30篇、视觉分析10篇、机器学习20篇、大数据分析20篇、图像识别30篇、人工智能40篇、 20 篇关于Python 安全性的文章,以及10 篇关于其他技术的文章。您的关注、点赞、转发是对秀章最大的支持。知识无价,人有感情。希望我们都能幸福,在人生的道路上共同成长。
本系列文章主要讲解Python OpenCV图像处理和图像识别知识。前期主要讲解图像处理的基础知识、OpenCV的基本使用、常见图像绘制方法、图像几何变换等,中期讲解图像处理的各种操作,包括图像点操作、形态学操作等。处理、图像锐化、图像增强、图像平滑等,后期研究图像识别、图像分割、图像分类、图像特效处理和图像处理相关应用。
第二部分将讲解图像运算和图像增强,上一篇文章介绍图像锐化的Roberts算子和Prewitt算子。这篇文章将继续讲解图像锐化知识。在图像收集和传输过程中,可能会受一些外界因素造成图像模糊和有噪声的情况,从而影响到后续的图像处理和识别。此时可以通过图像锐化和边缘检测,加强原图像的高频部分,锐化突出图像的边缘细节,改善图像的对比度,使模糊的图像变得更清晰。图像锐化和边缘检测主要包括一阶微分锐化和二阶微分锐化,本文主要讲解常见的图像锐化和边缘检测方法,即Sobel算子和Laplacian算子。希望文章对您有所帮助,如果有不足之处,还请海涵。
1. 图像锐化1. 一阶微分算子2. 二阶微分算子2. Roberts 算子3. Prewitt 算子4. 摘要下载地址:记得点赞喔 O(_)O
https://github.com/eastmountyxz/Python-zero2one 600多页开源电子书:https://github.com/eastmountyxz/HWCloudImageRecognition前文赏析:
第1 部分基础语法
【Python从零到一】1.为什么要学习Python以及基本语法详解【Python从零到一】2.条件语句、循环语句和函数的语法基础【Python从零到一】3.语法基础文件操作、CSV文件读写及面向对象第2部分网络爬虫
【Python从零到一】4.网络爬虫入门基础知识及正则表达式抓取博客案例【Python从零到一】5.网络爬虫BeautifulSoup基本语法详解【Python从[从零到一] 6. 网络爬虫BeautifulSoup 爬取豆瓣前250 部电影详解【Python 从零到一】 7. 网络爬虫爬取豆瓣前250 部电影的请求及CSV 存储【Python 从零到一】 8. 详解MySQL基础知识及数据库操作讲解【Python从零到一】9.网络爬虫Selenium基础技术一万字详解【Python从零到一】10.爬取的在线百科知识一万字详解by Selenium(NLP语料库建设必备技能)第三部分数据分析与机器学习
【Python从零到一】11.数据分析的Numpy、Pandas、Matplotlib、Sklearn入门知识一万字详解【Python从零到一】12.机器学习回归分析一万字总结【 Python从零到一】13.机器学习聚类分析一万字总结全网首发(K-Means、BIRCH、层次聚类、树聚类)【Python从零到一】14.五万-机器学习分类算法词总结全网首发(决策树、KNN、SVM、分类对比实验)【Python从零到一】15.文本挖掘的数据预处理、Jieba工具和文本聚类详解【Python从零到一】16.文本挖掘词云热点及LDA主题分布分析,一万字详解【Python从零到一】17.Matplotlib、Pandas、Echarts进行可视化分析详解及一万字入门【Python从零到一】 18.可视化分析的Basemap地图包详解【Python从零到一】19.热图和箱线图绘制详解以及可视化分析的应用【Python从零到一】 20.Seaborn绘图可视化分析详解【Python从零到一】21.Pyechart绘图可视化分析一万字详解【Python从零到一】22.OpenGL绘图可视化分析一万字详解【Python从零到一】23.十大机器学习算法决策树分类分析详解(一)【Python从零到一】二十四。十大机器学习算法KMeans聚类分析详解(二)【Python从零到一】二十五十大机器学习算法的KNN算法和图像分类详解(三)【Python从零到一】 26.十大机器学习算法的朴素贝叶斯算法和文本分类详解(四)【Python从零到一】27.十大机器学习算法之线性回归算法详解(5)【Python从零到一】28.十大机器学习算法之SVM算法详解(6) )【Python从零到一】29.十大机器学习算法之随机森林算法详解(七)【Python从零到一】30.逻辑回归算法的应用及恶意请求检测详解十大机器学习算法(八)【Python从零到一】31.十大机器学习算法Boosting之和AdaBoost应用详解(九)【Python从零到一】32.应用详解十大机器学习算法之层次聚类和树状图聚类(十)第四部分:Python图像处理基础
【Python从零到一】三十三。图像处理基础知识:什么是图像处理以及OpenCV配置【Python从零到一】三十四。 OpenCV ——显示读取、修改和保存图像详解【Python从零到一】三十五 OpenCV图像处理基础知识中绘制各种几何图形【Python从零到一】三十六。图像处理基础知识中图像算术和逻辑运算详解【Python从零到一】三十七。图像处理基础知识中的图像融合处理和ROI区域绘制【Python从零到一】38.图像处理基础知识中的图像几何变换(平移、缩放和旋转)【Python从零到一】39.图像基础知识第40章. 图像几何变换(镜像仿射透视)【Python从零到一】 第40章. 从图像处理基础开始的图像量化处理章节【Python从零到一】 第41章. 从图像基础开始图像采样处理处理篇【Python从零到一】42.图像处理基础知识:图像金字塔上采样和下采样第五部分Python图像运算和图像增强
【Python从零到一】43.图像增强与运算篇中图像点运算和图像灰度处理【Python从零到一】44.图像增强与运算篇中图像灰度线性变换详解【Python从零开始】 45. 图像增强与运算章节中图像灰度非线性变换详解【Python从零到一】 46. 图像增强与运算章节中图像阈值处理【Python从零到一】 47. 详解图像增强与运算章节中的腐蚀和膨胀【Python从零到一】48。图像增强与运算章节中的形态学开、闭和梯度操作【Python从零到一】49。图像增强与运算篇【Python从零到一】中的顶帽运算和底帽运算50.图像增强与运算篇【Python从零到一】中的图像直方图理论知识与绘图实现51.图像的对比分析增强与运算章节中的图像灰度直方图。一万字详解【Python从零到一】52.图像增强与运算章节中的图像掩模直方图和HS直方图【Python从零到一】53.图像增强与运算章节中的直方图均衡处理【Python从零到一】54.图像增强与运算章节中的局部直方图均衡和自动颜色均衡处理【Python从零到一】55.图像平滑(Mean Filter、Box)图像增强与运算篇【Python从零到一】中的滤波器(高斯滤波器)56.图像增强与运算篇【Python从零到一】零到一中的图像平滑(中值滤波器、双边滤波)五十-七。图像锐化图像增强与运算章节中的Roberts和Prewitt算子实现边缘检测【Python从零到一】五十八。图像增强与运算章节中的图像锐化Sobel和Laplacian算子实现边缘检测第6部分Python图像识别和高级图像案例
第7 部分NLP 和文本挖掘
第八部分人工智能简介
第九部分网络攻防与人工智能安全
第10部分:实用知识图谱构建
扩展版块人工智能高级案例
Sobel 算子是一种用于边缘检测的离散微分算子,结合了高斯平滑和微分求导。该算子用于计算图像亮度的近似值。根据图像边缘附近的亮度,将该区域中超过一定数量的特定点记录为边缘。 Sobel算子在Prewitt算子的基础上增加了权重的概念。它认为相邻点之间的距离对当前像素有不同的影响。距离像素越近,对当前像素的影响越大,从而实现图像锐化和突出边缘轮廓[1-4]。
Sobel算子的边缘定位比较准确,常用于噪声较多、灰度梯度较大的图像。其算法模板如式(1)所示,其中dx代表水平方向,dy代表垂直方向[3]。
像素计算公式如下:
Sobel算子像素最终的计算公式如下:
Sobel算子根据像素上下、左右相邻点的灰度级加权差来检测边缘,在边缘处达到极值。它对噪声有平滑作用,并提供更准确的边缘方向信息。因为Sobel算子结合了高斯平滑和微分求导(微分),所以结果会更加抗噪。当精度要求不是很高时,Sobel算子是比较常用的边缘检测方法。
Python和OpenCV将Sobel算子封装在Sobel()函数中,其函数原型如下:
dst = Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])
src代表输入图像
dst表示输出边缘图,其大小和通道数与输入图像相同
ddepth 表示目标图像所需的深度。对于不同的输入图像,输出的目标图像具有不同的深度。
dx表示x方向的微分阶数,取值1或0
dy表示y方向的差分阶数,取值1或0
ksize表示Sobel算子的大小,其值必须为正数且为奇数。
scale表示缩放导数的比例常数,默认没有缩放系数
delta 表示在将结果存储到目标图像之前添加到结果中的可选增量值
borderType 表示边框模式。有关更多详细信息,请参阅BorderTypes。注意,Sobel算子处理后,还需要调用convertScaleAbs()函数计算绝对值,并将图像转换为8位图像进行显示。算法原型如下:
dst = convertScaleAbs(src[, dst[, alpha[, beta]]])
src代表原始数组
dst表示输出数组,深度为8位
alpha 代表缩放因子
beta表示原数组元素缩放后增加的值。 Sobel算子的实现代码如下。
# -*- 编码: utf-8 -*-
#By:伊斯特蒙特
导入CV2
将numpy 导入为np
将matplotlib.pyplot 导入为plt
#读取图像
img=cv2.imread('罗.png')
lenna_img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#灰度图像处理
greyImage=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#Sobel运算符
x=cv2.Sobel(grayImage, cv2.CV_16S, 1, 0) #求x的一阶导数
y=cv2.Sobel(grayImage, cv2.CV_16S, 0, 1) #求y的一阶导数
absX=cv2.convertScaleAbs(x)
绝对值=cv2.convertScaleAbs(y)
索贝尔=cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
#用于正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图形
Titles=['原图', '索贝尔算子']
图像=[lenna_img, 索贝尔]
对于范围(2): 内的i
plt.subplot(1,2,i+1), plt.imshow(images[i], '灰色')
plt.title(标题[i])
plt.xticks([]),plt.yticks([])
plt.show()的运行结果如图1所示:
拉普拉斯算子是n维欧几里德空间中的二阶微分算子,常用于图像增强和边缘提取领域。它通过灰度差计算邻域内的像素。基本流程是:
确定图像中心像素的灰度值和周围其他像素的灰度值;如果中心像素点的灰度值较高,则增大中心像素点的灰度值;否则,降低中心像素的灰度值以实现图像锐化。在算法实现过程中,拉普拉斯算子计算邻域内中心像素的四个或八个方向的梯度,然后将梯度相加,以确定中心像素的灰度与邻域内其他像素的灰度之间的关系。邻居。最后,通过梯度运算的结果,调整像素灰度[2]。
连续二元函数f(x,y),其拉普拉斯运算定义为:
拉普拉斯算子分为四邻域和八邻域。四邻域是求邻域中心像素四个方向的梯度,八邻域是求八个方向的梯度。其中,四邻点模板如式(5)所示:
其像素的计算公式可以简化为:
通过模板可以发现,当邻域像素灰度相同时,模板的卷积运算结果为0;当中心像素灰度高于邻域其他像素的平均灰度时,模板的卷积运算结果为正数。当中心像素的灰度低于邻域其他像素的平均灰度时,模板的卷积为负。通过对卷积运算的结果进行适当的衰减因子处理,并将其与原始中心像素相加,可以对图像进行锐化。
拉普拉斯算子的八邻域模板如下:
其像素的计算公式可以简化为:
Python和OpenCV将拉普拉斯算子封装在Laplacian()函数中,其函数原型如下:
dst = Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
src代表输入图像
dst表示输出边缘图,其大小和通道数与输入图像相同
ddepth表示目标图像所需的深度
ksize 表示用于计算二阶导数的滤波器的孔径大小。它的值必须是正数和奇数,默认值为1。更多详细信息,请参阅getDerivKernels
scale 表示用于计算拉普拉斯算子值的可选缩放因子。默认值为1,更多详细信息请参阅getDerivKernels
delta 表示在将结果存储到目标图像之前添加到结果的可选增量值。默认值为0
borderType 表示边框模式。有关更多详细信息,请参阅BorderTypes。注意,拉普拉斯算子实际上主要使用了索贝尔算子的运算。将Sobel算子计算出的图像x方向和y方向的导数相加,得到输入图像。图像锐化结果。
同时,进行拉普拉斯算子处理后,还需要调用convertScaleAbs()函数计算绝对值,将图像转换为8位图像进行显示。算法原型如下:
dst = convertScaleAbs(src[, dst[, alpha[, beta]]])
src代表原始数组
dst表示输出数组,深度为8位
alpha 代表缩放因子
beta表示原数组元素缩放后增加的值。当ksize=1时,Laplacian()函数使用33孔径(四邻域模板)进行变换处理。以下代码使用ksize=3 的拉普拉斯算子进行图像锐化。代码如下:
# -*- 编码: utf-8 -*-
#By:伊斯特蒙特
导入CV2
将numpy 导入为np
将matplotlib.pyplot 导入为plt
#读取图像
img=cv2.imread('罗.png')
lenna_img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#灰度图像处理
greyImage=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#拉普拉斯算法
dst=cv2.拉普拉斯(grayImag
e, cv2.CV_16S, ksize = 3) Laplacian = cv2.convertScaleAbs(dst) #用来正常显示中文标签 plt.rcParams['font.sans-serif']=['SimHei'] #显示图形 titles = ['原始图像', 'Laplacian算子'] images = [lenna_img, Laplacian] 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()其运行结果如图2所示: 边缘检测算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此需要采用滤波器来过滤噪声,并调用图像增强或阈值化算法进行处理,最后再进行边缘检测。下面是采用高斯滤波去噪和阈值化处理之后,再进行边缘检测的过程,并对比了四种常见的边缘提取算法。 # -*- 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) #高斯滤波 gaussianBlur = cv2.GaussianBlur(grayImage, (3,3), 0) #阈值处理 ret, binary = cv2.threshold(gaussianBlur, 127, 255, cv2.THRESH_BINARY) #Roberts算子 kernelx = np.array([[-1,0],[0,1]], dtype=int) kernely = np.array([[0,-1],[1,0]], dtype=int) x = cv2.filter2D(binary, cv2.CV_16S, kernelx) y = cv2.filter2D(binary, cv2.CV_16S, kernely) absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0) #Prewitt算子 kernelx = np.array([[1,1,1],[0,0,0],[-1,-1,-1]], dtype=int) kernely = np.array([[-1,0,1],[-1,0,1],[-1,0,1]], dtype=int) x = cv2.filter2D(binary, cv2.CV_16S, kernelx) y = cv2.filter2D(binary, cv2.CV_16S, kernely) absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) Prewitt = cv2.addWeighted(absX,0.5,absY,0.5,0) #Sobel算子 x = cv2.Sobel(binary, cv2.CV_16S, 1, 0) y = cv2.Sobel(binary, cv2.CV_16S, 0, 1) absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0) #拉普拉斯算法 dst = cv2.Laplacian(binary, cv2.CV_16S, ksize = 3) Laplacian = cv2.convertScaleAbs(dst) #效果图 titles = ['Source Image', 'Binary Image', 'Roberts Image', 'Prewitt Image','Sobel Image', 'Laplacian Image'] images = [lenna_img, binary, Roberts, Prewitt, Sobel, Laplacian] for i in np.arange(6): plt.subplot(2,3,i+1),plt.imshow(images[i],'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()输出结果如图3所示。其中,Laplacian算子对噪声比较敏感,由于其算法可能会出现双像素边界,常用来判断边缘像素位于图像的明区或暗区,很少用于边缘检测;Robert算子对陡峭的低噪声图像效果较好,尤其是边缘正负45度较多的图像,但定位准确率较差;Prewitt算子对灰度渐变的图像边缘提取效果较好,而没有考虑相邻点的距离远近对当前像素点的影响;Sobel算子考虑了综合因素,对噪声较多的图像处理效果更好。