李海玲, 张昊
(西安航空学院 计算机学院, 西安 710077)
卷积[1-2]一词最开始出现在信号与线性系统中,信号与线性系统中讨论的就是信号经过一个线性系统以后发生的变化。而现实情况常常是一个信号前一时刻的输出影响着这一时刻的输出,所以一般利用系统的单位响应与系统的输入求卷积,以得到系统的输出信号。卷积定义为两个变量在某范围内相乘后求和的结果,如果卷积的变量是序列x(n)和h(n),则卷积的结果y(n)由式(1)得到式(1)。
*h(n)
(1)
其中星号*表示卷积。在数字图像处理[3]和卷积神经网络[4](Convolutional Neural Networks,简称CNN)等方面,卷积应用也非常广泛,利用卷积运算可以对图像进行空域增强,在卷积神经网络的学习中,首当其冲的操作便是卷积。
数字图像是一个二维的离散信号,对数字图像做卷积操作就是利用卷积核(卷积模板)在图像上滑动,将图像点上的像素灰度值与对应的卷积核上的数值相乘,然后将所有相乘后的值相加作为卷积核中间像素对应的图像上像素的灰度值,并最终滑动完所有图像的过程,输出结果仍然是一副图像[5]。卷积具体过程,如图1所示。
(a)*(b)=(c)
图1 数字图像卷积过程
其中图1(a)为卷积前的图像点上的像素灰度值,图1(b)为卷积核,图1(c)为卷积结果。
从图像卷积过程可以看出,卷积操作会导致图像变小,如图1所示。原始图像尺寸为5×5,卷积核尺寸为3×3,一次卷积结束卷积核移动步长为1个像素,卷积结果尺寸变为3×3。这是因为在卷积运算过程中要用到输入图像中与卷积核中心的邻域所对应的像素,当卷积核滑到图像边界,比如图像底部的像素,而它的下面已经没有像素了,卷积核一部分数据则恰好落在了处理图像的外围,这样就失去了与之相对应计算的数据。
解决这个问题有两种办法[5]:一种是忽略这些边界处的像素,只考虑图像内部与边界距离小于等于卷积核半径的像素。另一种是将输入图像进行扩展,使得卷积结果得到的图像尺寸和输入图像尺寸一致。第一种办法在原始图像尺寸比较大且感兴趣目标在图像内部时常可以接受,因为此时图像边界损失不影响整体效果。然而如果卷积核移动步长增大或是卷积核变大,图像边界损失将愈加严重。所以经常的一种做法是人为的在卷积操作之前对图像边界进行扩展。
如前所述,当卷积核到达图像边界,为了得到和原始图像大小相同的结果,降低图像边界损失,需要先对原始图像做边界扩展填充处理。边界扩展填充处理需要解决两个问题,第一,边界扩展多少个像素;第二,扩展的边界用什么值填充。
从图(1)可知,边界填充数量跟原始图像尺寸、卷积核尺寸、移动步长均有关系。假设原始图像尺寸为M×M,卷积核大小为N×N,边缘填充像素个数为pad,移动步长为step。则卷积后图像的尺寸m为式(2)。
m=(M-N+2×pad)/step+1
(2)
要得到m=M,即卷积前后的图像尺寸不变,根据式(2),当给定卷积核移动步长,便可计算出边界填充像素的个数。
确定好边界填充的像素数目后,新增行或列中像素值可用不同的方法来确定。最简单的方法就是全用0填充,缺点是有可能导致图像边界处有明显的不连贯;或者用其在原图像中4-邻域像素的值填充,4个角上新增像素的值用其在原图像中8-邻域像素的值填充;或者将图像在水平和垂直方向看作是周期循环的,最后一行(或列)之后是图像的第一行(或列),从而用相应的行(或列)填充;或者利用外插技术,根据一定的规则进行边界像素值填充[5]。
在卷积神经网络中,边界扩展的方法主要有边界补0、边界复制、边界镜像、边界对称和边界块复制等[6]。OpenCV的帮助文档中提供了几种不同的边界扩展策略,如表1所示。
表1 OpenCV中边界扩展类型及含义
其中“|”表示的是图像的边界,两个“|”中间是图像的内容,最后一个边界拓展策略还要额外给定一个i值,表示用i值对边界进行填充。
其中BORDER_REPLICATE体现的就是边界复制的意思,BORDER_REFLECT表示用边界镜像方式填充,BORDER_REFLECT_101表示对称填充,BORDER_WRAP表示边界以块复制填充,BORDER_CONSTANT表示用指定的常量i填充,当i=0时即为边界补0的含义。
在OpenCV中,边界扩展以原图为基准,逐行处理,先扩展左边界,再扩展右边界,最后扩展上边界和下边界,以图1(a)为例,边界扩展2个像素,各种扩展后的图像如图2所示。
(a)
(b)
(c)
(d)
(e)
其中图2(a)为边界补0结果,图2(b)为边界复制结果,图2(c)为边界镜像结果,图2(d)为边界对称结果,图2(e)为边界块复制结果。
如果边界填充的像素数为1,则边界复制和边界镜像的结果是相同的,为了区分每一种边界扩展方法,在OpenCV中,选用高斯-拉普拉斯算子(Laplacian of Gaussian,简称LoG算子)作为卷积核,对图像进行了边界扩展测试和实现。LoG算子常用于数字图像的边缘提取和二值化,它把Gauss平滑滤波器和Laplacian锐化滤波器结合起来,先平滑掉噪声,再进行边缘检测,所以效果会更好[7-9]。
OpenCV中用函数filter2D来实现对图像或矩阵的卷积操作。这个函数本质上做的是协相关操作,但是当核算子是对称的,则协相关操作也是卷积操作。copyMakeBorder函数的功能是设置边界扩展的方式及填充值的数量。在对图片进行卷积处理之前,先调用copyMakeBorder函数进行图像边界扩充,然后调用函数filter2D实现图片卷积,最后再对卷积结果进行剪切,从而得到和原始图片相同尺寸的对应卷积结果[10]。
实验中选用标准原始图像尺寸为512×512,卷积核为LoG算子,大小为5×5的模板,如图3所示。
图3 常用的高斯-拉普拉斯算子
移动步长设置为1,根据式(2),要得到原始图像的尺寸,边界填充像素个数为2。实验结果,如图4所示。
其中图4(a)为边界补0后的卷积结果,图4(b)为边界复制后的卷积结果,图4(c)为边界镜像填充后的卷积结果,图4(d)为边界对称填充后的卷积结果,图4(e)为块复制填充后的卷积结果,图4(f)为原始图像。
(a)
(b)
(c)
(d)
(e)
(f)
由于图像边缘只填充了2个像素,不同边界填充的卷积结果肉眼不易区分,实验结果数据,如图5所示。
图5 不同边界扩充结果和卷积结果数据
为了说明情况,图中只列出了图像最前面的36个数据。其中6 × 6(前)表示原始图像的前36个数据,6 × 6(后)表示原始图像前6行、倒数6列的36个数据。实验数据给出了五种不同边界扩充方法的结果以及每一种方法扩充后的卷积结果。
卷积是数字图像处理和卷积神经网络中常用的一个技术,卷积操作会导致图像变小从而损失图像边界。为得到和原始图像尺寸相同的卷积结果,本文研究了各种边界扩展方法及填充方式,并在OpenCV中以高斯-拉普拉斯算子为卷积核,对标准图像进行了各种边界填充的实现以及对应的卷积实现和裁剪,为进一步开展卷积神经网络研究和深度学习奠定基础。