APP下载

基于模糊图像边缘检测算法的改进

2020-09-02王伟家

现代计算机 2020年21期
关键词:像素点算子灰度

王伟家

(兰州大学信息科学与工程学院,兰州730000)

0 引言

边缘是一幅图像中最重要的特征之一,它会携带着一幅图片中的绝大多数信息,例如,它可以反映图像的面积、图像的形状、图像的周长、图像之间的包含关系等最基本的特征。那么边缘又是如何定义的?所谓边缘是指其周围像素灰度值有明显变化的像素点的集合,而边缘检测算法的目的便是准确的找到这些像素点。当前存在的大部分边缘检测算法即是根据像素点在边缘区域的跳跃性变化来检测,反映在数学上即是根据边缘邻近的一阶或二阶方向导数的变换规律,来判断图像边缘点。

基于一阶和二阶导数来进行图像边缘检测的算法也已经存在多种,例如:结合了高斯平滑和微分求导,并采用了卷积核来检测图像边缘的Sobel 算子;使用图像梯度以及对图像进行二阶求导的Laplace 算子;利用高斯平滑滤波器去除噪音,并采用一阶求导的有限差分来检测图像边缘的Canny 算子等。上述的各种算子已经存在相应的集成函数,但是,上述的边缘检测技术,对图像中各区域像素灰度对比度大的边缘提取效果较好,也就是所谓的边缘明显的图像,而对对比度较小的边缘,其检测效果则不理想,有的模糊图像的边缘甚至根本无法检测出来。

针对于上述模糊图像的边缘检测效果差的情况,设计了一种利用边缘像素点与周围像素点的差值与阈值之间的关系来检测边缘的算法。这种算法主要经过四个核心的步骤:

图1

1 模糊图像边缘检测的分析与设计

1.1 区域划分

由于一幅图像中可能存在着多个图形,或者可能存在多个图形嵌套的情况,那么这便会使图像中存在多个图像的边缘,而对于要检测的某一个图形来说,其

他多余的图形的边缘信息便会对要检测的图形的边缘产生干扰。因此,第一部分所要做的工作便是将图片中所要检测的图形的外接矩形区域切割出来,可以利用图像查看器将要检测图像的左上角以及图像的右下角信息记录下来,利用这两个信息确定出包含要检测图像的外接矩形。

1.2 阈值选取、边缘检测

由于图像分为彩色图像和灰度图像,所以在相应的外接矩形区域划分出来之后,利用OpenCV 中的cvt-Color 方法将相应的彩色图像转换为灰度图像,针对转变为的灰度图像,设置适当的阈值为T,对灰度图像的每一行选取适当的像素点为边缘像素点。

下面主要为实现的思想:

假设处理的图片为img,利用Python 中的len(img[0])求出像素点的列数,利用len(img)求出像素点的行数。由于要求模糊图像的边缘,而边缘分为封闭图形的边缘和未封闭图形的边缘,封闭图形的边缘例如圆形、正方形等,未封闭图形的边缘例如半圆、半正方形等。可以利用上述图形边缘的性质,在检测模糊图像边缘时,对于每一行分别从左向右、从右向左进行检测。从左向右检测时,当检测到第一组符合边缘性质的像素点时,将符合要求的像素点的位置记录下来,并停止从左向右检测此行的边缘。从右向左检测时,当检测到第一组符合边缘性质的像素点时,将符合要求的像素点的位置记录下来,并停止从右向左检测此行的边缘。上述步骤完成后,对于封闭图形来说,每一行像素点中都已经暂时确定了左边缘和右边缘,对于未封闭图形来说,每一行像素点都会集中到一组边缘像素点。

图2 封闭模糊图形检测边缘示意图

图3 未封闭模糊图形检测边缘示意图

具体的实现细节如下:

设置当前行的下标为i,从左向右检测边缘时,在每一行像素点中从第五个像素点开始,依次进行判断,设为列像素点j。当在当前行i 下,某一个j 开始的像素点与j-5 的像素点的差值超过设置的阈值时,判断j接下来的连续k 个像素点是否与j+k-5 的像素点的差值超过阈值。如果从j 开始的k 个像素点与前面的像素点都超过了设定的阈值,就将其中的img[i][j]像素点暂定为边缘像素点,即满足下列的公式:

上述公式中j 的范围为[5,col],i 的范围为[1,row](col 为图像像素点的列数,row 为图像像素点的行数),并且上述公式实现从左向右检测左边缘,下述公式实现的是从右向左检测右边缘:

上述公式中j 是从col 开始,到5 结束,i 的范围为[1,row]。

1.3 去除噪音

上述阈值选取和边缘检测步骤完成之后,模糊图像的大体边缘已经可以呈现出来,但是,还是存在一个问题:图中检测的边缘中会存在着部分的噪音点,这些噪音点组成的像素点的集合也会被上述的步骤误判为边缘,那么,这就会导致这一块的边缘检测出现错误,这一部分所要做的就是去除图片中的噪音点。

实现的思想如下:

当1.2 步骤完成之后,对于每一行像素点来说,依靠步骤2 已经找到了疑似边缘的像素点,并且这个像素点的横纵坐标已经记录下来了。设定一个阈值T,假定此时的行下标为i,找到的像素点的纵坐标为pixel[i],这时,求出[i,pixel[i]]这个像素点与[i-1,pixel[i-1]]、[i-2,pixel[i-2]]、[i+1,pixel[i+1]]、[i+2,pixel[i+2]]像素点的距离总和,当距离总和的值超过设定的阈值T 时,判定此像素点为噪音点,当求得的像素点的距离总和小于设定的阈值T 时,判定此像素点为边缘点。

假设检测出来的噪音点的坐标为(i,pixel[i]),噪音点的坐标(i,pixel[i])与(i-1,pixel[i-1])、(i+1,pixel[i+1])的距离超过了设定的阈值,那么此时我们可以使用(i-1,pixel[i-1])以及(i+1,pixel[i+1])来对噪音点进行纠正,取pixel[i-1]和pixel[i+1]的中值来替代pixel[i],就可以有效地将噪音点去除,使得检测模糊图片的边缘达到较好的效果。

1.4 边缘像素值替换

经过上述的三个步骤之后,已经可以十分准确地确定出模糊图片的边缘,此时,图片边缘点的坐标已经记录了下来,接下来要做的工作便是将这些边缘在图片中表示出来,这里我们采用的是像素点值替换的方法:确定图片的边缘点之后,重新遍历图片的边缘点,将图片边缘点的像素值全部替换为255,那么此时,再次显示图片的时候便可以直观地观察到模糊图像的边缘。

1.5 算法步骤

(1)利用OpenCV 中的imread()函数读入需要检测的模糊图像,并使用cvtColor 函数将图像统一转变为灰度图像,之后利用Python 中的len()函数求出图像的横纵像素的总数,分别记为col 和row,用于表示行数和列数。

(2)利用open()函数来读取存放检测图像的外接矩形的左上角和右下角的坐标,使用数组存放起来。

(3)依靠步骤2 所存放外接矩形的左上角和右下角的坐标,指明了一张图片在哪一个区域开始进行检测,此时,循环的上界和下界便已经确定下来。对图像检测区域的每一行分别从左到右、从右到左检测边缘,并提前设置好适当的阈值。先执行从左向右检测,当此行下存在一组像素点符合行检测边缘的要求时,记录下此像素点的行坐标和列坐标,跳出循环,如果此行下所有的像素点都无法满足边缘点的要求,将此行对应的数组值设置为-1。从左向右检测完毕之后,此时图像的左边部分的边缘点已经找出并存储,此时,执行从右向左的边缘检测,同样,当检测到符合要求的像素点时,记录下此像素点的坐标,如果没有找到符合要求的像素点,将相应的数组值设置为-1。

(4)步骤3 求出每一行的边缘点,此时求出的边缘点中还存在着噪音点,之后利用每一行的边缘点与此行的前两行与后两行之间的距离与设置的阈值之间的大小来判断是否是噪音点。如果检测的是噪音点,利用此行的前一行和后一行的中值来纠正噪音点,并存放其纠正后的像素点的坐标,最后达到去除噪音点的目的。

(5)此时精确的边缘点已经全部存在相应的数组中,最后利用一个循环,将每一行的边缘像素点的值替换为255,利用OpenCV 中的imwrite()函数将处理好的图片保存在特定的文件夹下,至此,模糊图像的边缘检测已经完成。

1.6 算法的时间复杂度和空间复杂度的分析

由于要对模糊图像中的每一个像素进行分析与判断,所以需要遍历图像中的每一行和每一列,所以该算法的时间复杂度应该为O(col×row),col 表示的是检测图像的列数,row 表示的是检测图像的行数。

空间复杂度:由于该算法是对图像的每一行分别从左到右、从右向左寻找边缘点,所以每一行需要2 个位置来存储像素点,而图像中一共有row 行,则算法的空间复杂度为O(2×row)。

2 实验过程以及结果分析

实验过程均运行在VS code 的Python 环境下,需要依赖Python 下的OpenCV 函数库以及numpy 函数库,图像数据为1 组模糊图像,在附件中保存。

下述的实验过程将会通过本篇文章中介绍的算法与传统的边缘检测算法Sobel、Canny、Laplacian 进行比较来分析模糊图像边缘检测的优劣。实验中的图片都是事先经过了OpenCV 的灰度处理,并且经过了区域划分的操作。

图中的a 表示的是二氧化硅在589 摄氏度下的灰度图,图中的边缘表现的非常模糊。

C.1 图片和C.2 的图片都是利用Sobel 算子检验边缘的效果图,C.1 和C.2 都是使用了大小为5 的卷积核进行的操作,不过C.1 是分别从x 和y 方向分别进行了求导,最后通过addWeighted()方法将两个方向的结果合并到了一起,C.2 是直接运行Sobel 函数对x 和y 方向一起进行了求导,图中展示的即为效果图。从C.1的效果图可以看出,对x 和y 方向分别进行求导,最终通过addWeighted 函数合并在一起的边缘检测效果较好,但是,有一些模糊的边缘以及细节处,它未能有效的提取出边缘,其次,图中除去边缘之外,其他部分掺杂的噪音过多,这将会对边缘周长的计算或者图形面积的计算产生较大的干扰,C.2 的图片中对模糊图像的边缘检测效果较差,甚至无法辨认出模糊图像的边缘。

D 图片是利用了Canny 算子检验边缘的效果图,Canny 是通过使用两种不同的阈值分别用来检测图片中的强边缘和弱边缘,它的实现方法相对简单,Canny算子是利用了高斯模糊去除噪音,但这样会存在一个缺点,在去除噪音的过程中也同时会平滑边缘,这样做的结果是使边缘信息减弱,可能会在后面的步骤中漏掉一些需要的边缘,特别是一些孤立的边缘和弱边缘,可能在双阈值和联通计算中被剔除。可以预想到,如果加大高斯模糊的半径,就会对噪音的平滑力度进一步增强,也会使得后面得到的图像边缘图中的边缘明显减少。虽然噪音会有效地降低,但是,有效的边缘信息也消失了很多。图D 就是很好的证明,虽然D 图中的噪音大部分被平滑掉了,但是图中的边缘也同样被平滑掉了太多,导致检测的边缘十分不完整,只有一部分很明显的边缘被检测了出来。

E 图片是采用Laplacian 算子对模糊图片边缘检测的效果图,Laplacian 算法对图片中存在的噪音比较敏感,因此如果图片中存在大量的噪音,就导致模糊图片的边缘检测效果过差,从效果图可以看出,已经达到无法辨认边缘的层次,但实际中Laplacian 算子很少用来检测边缘,它大多数是用来判定边缘像素为图像的亮区还是暗区。

图4

经过C 图、D 图、E 图的比较,可以看到Sobel 边缘检测算子计算速度快,边缘连续性较好,但细节完整效果粗略,一些模糊的边缘以及一些细节之处,它未能有效地提取出边缘。而Canny 算子利用两种不同的阈值来见测强边缘和弱边缘,实现简单,但噪音平滑的过程中会使部分的边缘点减少,从而使检测边缘的无法较大。Laplacian 算子对噪音的敏感度太高,导致图片中的绝大多数噪音无法去除,对边缘的检测效果过差。从H 图可以看出,本文提出的边缘检测算法在选择合适的阈值的前提下的得到的图像边缘在边缘的定位精度。完整程度、连续性以及噪音去除方面都比Sobel 算子的效果强很多,虽然时间复杂度高一点,但是这种方法的抗噪能力比较强,当对模糊图片进行边缘检测时,此种方法的效果比较好,并且,由于噪音去除效果比较好,在计算模糊图形的面积和周长等方便也有很大的便利之处,但是,此种方法也有一些缺点,一方面实现起来需要写的代码比较繁杂,没有集成的函数,另一方面,如果图像的上下边缘较为平滑,那么检测上下边缘时的效果就比较差,从图中的H 中就可以观察到这一点,在图片的上边缘和下边缘的边缘检测相对于中间的边缘检测来说比较差。

3 结语

本文通过先对模糊图像的每一行像素点进行边缘检测达到检测行边缘的效果,但是,上述产生的边缘像素点存在大量的噪音,此时,再依据边缘的连续性,利用列像素点的关系达到去除噪音的目的。上述陈述的算法都是运用基本的数学运行来实现的,有思想简单的特点,其次,该算法基于的是灰度图像的检验,因为灰度图像与彩色图像的阈值选取差别较大,如果要对模糊的彩色图像进行边缘检测,可以先将其转变为灰度图像,之后,再对转变成的灰度图像进行边缘检测。

猜你喜欢

像素点算子灰度
航空滤光片阵列多光谱图像条带灰度调整算法
天津港智慧工作平台灰度发布系统和流程设计
基于局部相似性的特征匹配筛选算法
Domestication or Foreignization:A Cultural Choice
Arduino小车巡线程序的灰度阈值优化方案
一种X射线图像白点噪声去除算法
基于canvas的前端数据加密
QK空间上的叠加算子
图像采集过程中基于肤色理论的采集框自动定位
逼近论中的收敛性估计