Python从0到1丨细说图像增强及运算

python,细说,图像增强,运算 · 浏览次数 : 281

小编点评

# **图像锐化和边缘检测知识** ## ** Roberts算子** * Roberts算子是一种交叉差分算法,用于在灰度图像中寻找边缘线。 * Roberts算子的模板为 2x2 的矩阵,每个元素包含两个相邻像素的差分值。 * Roberts算子在水平方向和垂直方向的边缘检测中表现更明显。 ## **Prewitt算子** * Prewitt算子是一种图像边缘检测的微分算子,用于在灰度图像中寻找边缘线。 * Prewitt算子的模板为 3x3 的矩阵,每个元素包含三个相邻像素的差分值。 * Prewitt算子在水平方向和垂直方向的边缘检测中表现更明显。 ## **结果** * Roberts算子和Prewitt算子都可以用于在灰度图像中寻找边缘线。 * Roberts算子的结果在水平方向和垂直方向的边缘检测中表现更明显。 * Prewitt算子的结果在水平方向和垂直方向的边缘检测中表现更明显。 ## **代码** ```python # Roberts算子 kernelx = np.array([[-1,0,1],[-1,0,1],[-1,0,1]],dtype=int) kernely = np.array([[-1,0,1],[-1,0,1],[-1,0,1]],dtype=int) x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx) y = cv2.filter2D(grayImage, cv2.CV_16S, kernely) # Prewitt算子 prewitt_kernelx = np.array([[1,1,1],[0,0,0],[-1,-1,-1]],dtype=int) prewitt_kernely = np.array([[-1,0,1],[-1,0,1],[-1,0,1]],dtype=int) x = cv2.filter2D(grayImage, cv2.CV_16S, prewitt_kernelx) y = cv2.filter2D(grayImage, cv2.CV_16S, prewitt_kernely) # 添加权重 absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) # Roberts算子 result = cv2.addWeighted(absX,0.5,absY,0.5,0) # Prewitt算子 result_prewitt = cv2.addWeighted(absX,0.5,absY,0.5,0) ``` ## **结果** ``` Roberts算子 result = cv2.addWeighted(absX,0.5,absY,0.5,0) Prewitt算子 result_prewitt = cv2.addWeighted(absX,0.5,absY,0.5,0) ```

正文

摘要:本文主要讲解常见的图像锐化和边缘检测方法,即Roberts算子和Prewitt算子。

本文分享自华为云社区《[Python从零到壹] 五十七.图像增强及运算篇之图像锐化Roberts、Prewitt算子实现边缘检测》,作者: eastmount。

一.图像锐化

由于收集图像数据的器件或传输图像的通道存在一些质量缺陷,或者受其他外界因素的影响,使得图像存在模糊和有噪声的情况,从而影响到图像识别工作的开展。一般来说,图像的能量主要集中在其低频部分,噪声所在的频段主要在高频段,同时图像边缘信息主要集中在其高频部分。这将导致原始图像在平滑处理之后,图像边缘和图像轮廓模糊的情况出现。为了减少这类不利效果的影响,就需要利用图像锐化技术,使图像的边缘变得清晰[1]。

图像锐化处理的目的是为了使图像的边缘、轮廓线以及图像的细节变得清晰,经过平滑的图像变得模糊的根本原因是图像受到了平均或积分运算,因此可以对其进行逆运算,从而使图像变得清晰。微分运算是求信号的变化率,具有较强高频分量作用。从频率域来考虑,图像模糊的实质是因为其高频分量被衰减,因此可以用高通滤波器来使图像清晰。但要注意能够进行锐化处理的图像必须有较高的性噪比,否则锐化后图像性噪比反而更低,从而使得噪声增加比信号还要多,因此一般是先去除或减轻噪声后再进行锐化处理。这时需要开展图像锐化和边缘检测处理,加强原图像的高频部分,锐化突出图像的边缘细节,改善图像的对比度,使模糊的图像变得更清晰。

图像锐化和边缘提取技术可以消除图像中的噪声,提取图像信息中用来表征图像的一些变量,为图像识别提供基础。通常使用灰度差分法对图像的边缘、轮廓进行处理,将其凸显。图像锐化的方法分为高通滤波和空域微分法,本章主要介绍Robert算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr算子等[2-3]。

1.一阶微分算子

一阶微分算子一般借助空域微分算子通过卷积完成,但实际上数字图像处理中求导是利用差分近似微分来进行的。梯度对应一阶导数,梯度算子是一阶导数算子。对一个连续函数f(x,y),它在位置(x,y)梯度可表示为一个矢量:

梯度的模值为公式(2)所示。

梯度的方向在最大变化率方向上,梯度方向如公式(3)所示。

对于数字图像,导数可以用差分来近似,则梯度可以表示为:

在实际中常用区域模板卷积来近似计算,对水平方向和垂直方向各用一个模板,再通过两个模板组合起来构成一个梯度算子。根据模板的大小,其中元素值的不同,可以提出多种模板,构成不同的检测算子,后文中将对各种算子进行详细介绍。

由梯度的计算可知,在图像灰度变化较大的边沿区域其梯度值大,在灰度变化平缓的区域梯度值较小,而在灰度均匀的区域其梯度值为零。根据得到的梯度值来返回像素值,如将梯度值大的像素设置成白色,梯度值小的设置为黑色,这样就可以将边缘提取出来了,或者是加强梯度值大的像素灰度值就可以突出细节了达到了锐化的目的。

2.二阶微分算子

二阶微分算子是求图像灰度变化导数的导数,对图像中灰度变化强烈的地方很敏感,从而可以突出图像的纹理结构。当图像灰度变化剧烈时,进行一阶微分则会形成一个局部的极值,对图像进行二阶微分则会形成一个过零点,并且在零点两边产生一个波峰和波谷,设定一个阈值检测到这个过零点,如图1所示。

这样做的好处有两个,一是二阶微分关心的是图像灰度的突变而不强调灰度缓慢变化的区域,对边缘的定位能力更强;二是Laplacian算子是各向同性的,即具有旋转不变性,在一阶微分里,是用|dx|+|dy|来近似一个点的梯度,当图像旋转一个角度时,这个值就会变化,但对于Laplacian算子来说,不管图像怎么旋转,得到的相应值是一样的。

想要确定过零点要以p为中心的一个3×3领域,p点为过零点意味着至少有两个相对的领域像素的符号不同。有四种要检测的情况:左/右、上/下、两个对角。如果g(x,y)的值与一个阈值比较,那么不仅要求相对领域的符号不同,数值差的绝对值也要超过这个阈值,这时p称为一个过零点像素。二阶微分的定义为:

二阶微分在恒定灰度区域的微分值为零,在灰度台阶或斜坡起点处微分值非零,沿着斜坡的微分值为零。与一阶微分算子相比较,一阶微分算子获得的边界是比较粗略的边界,反映的边界信息较少,但是所反映的边界比较清晰;二阶微分算子获得的边界是比较细致的边界,反映的边界信息包括了许多的细节信息,但是所反映的边界不是太清晰。

二.Roberts算子

Roberts算子又称为交叉微分算法,它是基于交叉差分的梯度算法,通过局部差分计算检测边缘线条。常用来处理具有陡峭的低噪声图像,当图像边缘接近于正45度或负45度时,该算法处理效果更理想,其缺点是对边缘的定位不太准确,提取的边缘线条较粗。

Roberts算子的模板分为水平方向和垂直方向,如公式(6)所示,从其模板可以看出,Roberts算子能较好的增强正负45度的图像边缘[4]。

如公式(7)所示,分别表示图像的水平方向和垂直方向的计算公式。

Roberts算子像素的最终计算公式如下:

在Python中,Roberts算子主要通过Numpy定义模板,再调用OpenCV的filter2D()函数实现边缘提取[3]。该函数主要是利用内核实现对图像的卷积运算,其函数原型如下所示:

  • dst = filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
    – src表示输入图像
    – dst表示输出的边缘图,其大小和通道数与输入图像相同
    – ddepth表示目标图像所需的深度
    – kernel表示卷积核,一个单通道浮点型矩阵
    – anchor表示内核的基准点,其默认值为(-1,-1),位于中心位置
    – delta表示在储存目标图像前可选的添加到像素的值,默认值为0
    – borderType表示边框模式

在进行Roberts算子处理之后,还需要调用convertScaleAbs()函数计算绝对值,并将图像转换为8位图进行显示。其算法原型如下:

  • dst = convertScaleAbs(src[, dst[, alpha[, beta]]])
    – src表示原数组
    – dst表示输出数组,深度为8位
    – alpha表示比例因子
    – beta表示原数组元素按比例缩放后添加的值

最后调用addWeighted()函数计算水平方向和垂直方向的Roberts算子。其运行代码如下:

# -*- 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)
#Roberts算子
kernelx = np.array([[-1,0],[0,1]], dtype=int)
kernely = np.array([[0,-1],[1,0]], dtype=int)
x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
#转uint8 
absX = cv2.convertScaleAbs(x) 
absY = cv2.convertScaleAbs(y) 
Roberts = cv2.addWeighted(absX,0.5,absY,0.5,0)
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图形
titles = ['原始图像', 'Roberts算子'] 
images = [lenna_img, Roberts] 
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所示,左边为原始图像,右边为Roberts算子图像锐化提取的边缘轮廓。

三.Prewitt算子

Prewitt是一种图像边缘检测的微分算子,其原理是利用特定区域内像素灰度值产生的差分实现边缘检测。由于Prewitt算子采用3×3模板对区域内的像素值进行计算,而Robert算子的模板为2×2,故Prewitt算子的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显。Prewitt算子适合用来识别噪声较多、灰度渐变的图像,其计算公式如下所示。

具体的水平和垂直方向计算公式如下所示:

Prewitt算子像素的最终计算如公式(11)所示。

在Python中,Prewitt算子的实现过程与Roberts算子比较相似。通过Numpy定义模板,再调用OpenCV的filter2D()函数实现对图像的卷积运算,最终通过convertScaleAbs()和addWeighted()函数实现边缘提取,代码如下所示:

# -*- 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)
#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(grayImage, cv2.CV_16S, kernelx)
y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
#转uint8
absX = cv2.convertScaleAbs(x) 
absY = cv2.convertScaleAbs(y) 
Prewitt = cv2.addWeighted(absX,0.5,absY,0.5,0)
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图形
titles = ['原始图像', 'Prewitt算子'] 
images = [lenna_img, Prewitt] 
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()

最终运行结果如图3所示,左边为原始图像,右边为Prewitt算子图像锐化提取的边缘轮廓,其效果图的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显。

四.总结

本文主要介绍图像锐化和边缘检测知识,详细讲解了Roberts算子和Prewitt算子,并通过小珞珞图像进行边缘轮廓提取。图像锐化和边缘提取技术可以消除图像中的噪声,提取图像信息中用来表征图像的一些变量,为图像识别提供基础。

 

点击关注,第一时间了解华为云新鲜技术~

与Python从0到1丨细说图像增强及运算相似的内容:

Python从0到1丨细说图像增强及运算

摘要:本文主要讲解常见的图像锐化和边缘检测方法,即Roberts算子和Prewitt算子。 本文分享自华为云社区《[Python从零到壹] 五十七.图像增强及运算篇之图像锐化Roberts、Prewitt算子实现边缘检测》,作者: eastmount。 一.图像锐化 由于收集图像数据的器件或传输图像

Python从0到1丨图像增强及运算:形态学开运算、闭运算和梯度运算

摘要:本文主要介绍图像形态学处理,详细讲解了图像开运算、闭运算和梯度运算。数学形态学是一种应用于图像处理和模式识别领域的新方法,其基本思想是用具有一定形态的结构元素去量度和提取图像中对应形状以达到对图像分析和识别目的。 本文分享自华为云社区《[Python从零到壹] 四十八.图像增强及运算篇之形态学

Python从0到1丨带你认识图像平滑的三种线性滤波

摘要:常用于消除噪声的图像平滑方法包括三种线性滤波(均值滤波、方框滤波、高斯滤波)和两种非线性滤波(中值滤波、双边滤波),本文将详细讲解三种线性滤波方法。 本文分享自华为云社区《[Python从零到壹] 五十五.图像增强及运算篇之图像平滑(均值滤波、方框滤波、高斯滤波)》,作者:eastmount。

Python从0到1丨了解图像形态学运算中腐蚀和膨胀

摘要:这篇文章将详细讲解图像形态学知识,主要介绍图像腐蚀处理和膨胀处理。 本文分享自华为云社区《[Python从零到壹] 四十七.图像增强及运算篇之腐蚀和膨胀详解》,作者: eastmount 。 一.形态学理论知识 数学形态学的应用可以简化图像数据,保持它们基本的形状特征,并出去不相干的结构。数学

Python从0到1丨详解图像锐化的Sobel、Laplacian算子

本文主要讲解常见的图像锐化和边缘检测方法,即Sobel算子和Laplacian算子。

从0到1学Python丨图像平滑方法的两种非线性滤波:中值滤波、双边滤波

摘要:常用于消除噪声的图像平滑方法包括三种线性滤波(均值滤波、方框滤波、高斯滤波)和两种非线性滤波(中值滤波、双边滤波),本文将详细讲解两种非线性滤波方法。 本文分享自华为云社区《[Python从零到壹] 五十六.图像增强及运算篇之图像平滑(中值滤波、双边滤波)》,作者:eastmount。 常用于

深入理解Python多进程:从基础到实战

title: 深入理解Python多进程:从基础到实战 date: 2024/4/29 20:49:41 updated: 2024/4/29 20:49:41 categories: 后端开发 tags: 并发编程 多进程管理 错误处理 资源调度 性能优化 异步编程 Python并发库 引言 在P

深入理解Python协程:从基础到实战

title: 深入理解Python协程:从基础到实战 date: 2024/4/27 16:48:43 updated: 2024/4/27 16:48:43 categories: 后端开发 tags: 协程 异步IO 并发编程 Python aiohttp asyncio 网络爬虫 第1章:协程

详解Python 中可视化数据分析工作流程

本文分享自华为云社区《Python 可视化数据分析从数据获取到洞见发现的全面指南》,作者:柠檬味拥抱。 在数据科学和分析的领域中,可视化是一种强大的工具,能够帮助我们理解数据、发现模式,并得出洞见。Python 提供了丰富的库和工具,使得可视化数据分析工作流程变得高效而灵活。本文将介绍 Python

从原始边列表到邻接矩阵Python实现图数据处理的完整指南

本文介绍了如何使用Python将原始边列表转换为邻接矩阵,并进行了一系列的扩展和优化,以满足不同场景下的需求。