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

一.图画锐化

因为搜集图画数据的器材或传输图画的通道存在一些质量缺陷,或者受其他外界要素的影响,使得图画存在含糊和有噪声的状况,然后影响到图画辨认工作的展开。一般来说,图画的能量首要集中在其低频部分,噪声所在的频段首要在高频段,一起图画边际信息首要集中在其高频部分。这将导致原始图画在滑润处理之后,图画边际和图画概括含糊的状况呈现。为了减少这类不利作用的影响,就需求运用图画锐化技能,使图画的边际变得明晰[1]。

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

图画锐化和边际提取技能能够消除图画中的噪声,提取图画信息中用来表征图画的一些变量,为图画辨认供给根底。一般运用灰度差分法对图画的边际、概括进行处理,将其凸显。图画锐化的方法分为高通滤波和空域微分法,本章首要介绍Robert算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr算子等[2-3]。

1.一阶微分算子

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

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

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

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

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

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

关于数字图画,导数能够用差分来近似,则梯度能够表明为:

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

在实际中常用区域模板卷积来近似核算,对水平方向和笔直方向各用一个模板,再经过两个模板组合起来构成一个梯度算子。依据模板的巨细,其中元素值的不同,能够提出多种模板,构成不同的检测算子,后文中将对各种算子进行具体介绍。

由梯度的核算可知,在图画灰度改变较大的边际区域其梯度值大,在灰度改变陡峭的区域梯度值较小,而在灰度均匀的区域其梯度值为零。依据得到的梯度值来返回像素值,如将梯度值大的像素设置成白色,梯度值小的设置为黑色,这样就能够将边际提取出来了,或者是加强梯度值大的像素灰度值就能够杰出细节了达到了锐化的意图。

2.二阶微分算子

二阶微分算子是求图画灰度改变导数的导数,对图画中灰度改变强烈的地方很灵敏,然后能够杰出图画的纹路结构。当图画灰度改变剧烈时,进行一阶微分则会构成一个部分的极值,对图画进行二阶微分则会构成一个过零点,并且在零点两边发生一个波峰和波谷,设定一个阈值检测到这个过零点,如图1所示。

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

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

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

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

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

二.Roberts算子

Roberts算子又称为穿插微分算法,它是基于穿插差分的梯度算法,经过部分差分核算检测边际线条。常用来处理具有陡峭的低噪声图画,当图画边际接近于正45度或负45度时,该算法处理作用更理想,其缺陷是对边际的定位不太准确,提取的边际线条较粗。

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

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

如公式(7)所示,分别表明图画的水平方向和笔直方向的核算公式。

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

Roberts算子像素的终究核算公式如下:

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

在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算子图画锐化提取的边际概括。

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

三.Prewitt算子

Prewitt是一种图画边际检测的微分算子,其原理是运用特定区域内像素灰度值发生的差分完成边际检测。因为Prewitt算子选用33模板对区域内的像素值进行核算,而Robert算子的模板为22,故Prewitt算子的边际检测结果在水平方向和笔直方向均比Robert算子愈加显着。Prewitt算子合适用来辨认噪声较多、灰度渐变的图画,其核算公式如下所示。

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

具体的水平缓笔直方向核算公式如下所示:

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

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

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

在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算子愈加显着。

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

四.总结

本文首要介绍图画锐化和边际检测知识,具体讲解了Roberts算子和Prewitt算子,并经过小珞珞图画进行边际概括提取。图画锐化和边际提取技能能够消除图画中的噪声,提取图画信息中用来表征图画的一些变量,为图画辨认供给根底。

参考文献:

  • [1] 冈萨雷斯著,阮秋琦译. 数字图画处理(第3版)[M]. 北京:电子工业出版社,2013.
  • [2] 阮秋琦. 数字图画处理学(第3版)[M]. 北京:电子工业出版社,2008.
  • [3] 陈初侠. 图画滤涉及边际检测与增强技能研究[D].合肥工业大学, 2009.
  • [4] Eastmount. [Python图画处理] 四.图画滑润之均值滤波、方框滤波、高斯滤涉及中值滤波[EB/OL]. (2018-09-02). blog.csdn.net/Eastmount/a….
  • [5] Eastmount. [数字图画处理] 七.MFC图画增强之图画一般滑润、高斯滑润、Laplacian、Sobel、Prewitt锐化详解[EB/OL]. (2015-06-08). blog.csdn.net/eastmount/a… details/46378783.
  • [6] 毛星云. [OpenCV入门教程之九] 非线性滤波专场:中值滤波、双方滤波[EB/OL]. (2014-04-08). blog.csdn.net/poem\_qianm….
  • [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.

点击重视,第一时间了解华为云新鲜技能~