卷积的数学定义
在图像分析和图像处理中,卷积(convolution)是一种非常重要的运算。卷积是一个积分运算,其反应的是函数f(x)在另一个函数h(x)上移动时所叠加的量。函数f和h在有限域[0,t]上的一维卷积为:
(f∗h)(t)=∫0tf(τ)h(t−τ)dτ=∫0tf(t−τ)h(τ)dτ
需要注意的是,卷积积分的上下限实际为(−∞,+∞),但是此处我们假设负坐标部分的值为0,因此这里可以限定在区间[0,t]中。[1]
根据一维卷积的定义,我们可以得到函数f(x,y)在另一个函数h(x,y)上移动时的卷积:
(f∗h)(x,y)=∫−∞+∞f(a,b)h(x−a,y−b)dadb=∫−∞+∞f(x−a,y−b)h(a,b)dadb
数字图像分析中的卷积
数字图像是一个二维的离散数据,因此对于数字图像而言,需要将积分运算(∫)改为加和运算(∑),从而得到离散卷积(discrete convolution)。
对于数字图像而言,在图像平面上存在有限的定义域,对于定义域之外的离散卷积结果为0。因此,这个特点并不妨碍我们在数字图像上执行卷积运算。此时,卷积表示的是使用滤波器h对图像执行一个线性滤波处理。
我们在图像f(i,j)的一个局部邻域O内计算其所有像素的线性组合,邻域O中的各个像素的权重由h(i,j)来确定。因此,对于图像中的像素f(i,j),我们在其邻域O内使用滤波器h对其执行卷积运算,得到g(i,j):
g(i,j)=(m,n)∈O∑f(i−m,j−n)h(m,n)
在上式中,称h为卷积掩膜(convolution mask)或者滤波器,并且一般会选择具有奇数行和列的矩形邻域O,以方便确定领域的中心。[1]
利用高斯滤波器来模糊图像
通常,图像处理软件会提供“模糊”(blur)滤镜,使图片产生模糊的效果。具体如下图所示:

模糊的本质就是利用像素邻域O内其他像素的线性运算来计算该像素的值,从而提高该像素和邻域内其他像素之间的相关性。
模糊的方式和效果取决于线性运算时的滤波器h的选取。h的选择有很多,其中有一种就是高斯滤波器,其对应的模糊效果称之为“高斯模糊”。“高斯模糊”的本质就是利用高斯函数生成线性运算时各像素的权重,即利用高斯函数(当μ=0且各方向的σ相等时)生成滤波器h:
G(x,y)=2πσ21e−2σ2x2+y2
h中心点的坐标为(0,0),则整个h的坐标如下所示:

利用G(x,y)的公式,即可计算得到σ为指定值时的高斯滤波器h。具体细节此处不再赘述,具体可以参考:高斯模糊的算法。
不依赖其他库生成高斯滤波器
当μ=0且各方向的σ相等时,对于h(i,j)我们得到:
h(i,j)=i,j∑G(i,j)G(i,j)=i,j∑2πσ21e−(i2+j2)/(2σ2)2πσ21e−(i2+j2)/(2σ2)=2πσ21i,j∑e−(i2+j2)/(2σ2)2πσ21e−(i2+j2)/(2σ2)=i,j∑e−(i2+j2)/(2σ2)e−(i2+j2)/(2σ2)
使用python得到二维的高斯滤波器的代码如下:
1 2 3 4 5 6 7 8 9
| def gaussian_kernel_2d(sigma, width): if width == 1: return np.ones((1, 1))
kernel_radius = np.floor(width >> 1) ax = np.arange(-kernel_radius, kernel_radius + 1., dtype=np.float32) xx, yy = np.meshgrid(ax, ax) kernel = np.exp(-(xx**2 + yy**2) / (2. * sigma**2)) return kernel / np.sum(kernel)
|
详细代码可以参考高斯滤波器的生成和可视化。
滤波器的可分离特性
图像处理中的可分离滤波器(separable filter)可以写成两个更简单的滤波器的乘积。通常,可以把二维卷积运算分离为两个一维滤波器,从而降低图像的卷积运算复杂度。
例如,对于W×H的图像,如果采用n×n的二维滤波器,则卷积运算的复杂度为O(M⋅N⋅n2),而如果用两个1×n的一维滤波器,则卷积运算的复杂度为O(2M⋅N⋅n)。[4]
Karas Pavel和Svoboda David在Algorithms for Efficient Computation of Convolution[5]的3. Separable convolution部分指出:
给定一个行向量u=(u1,u2,...um)和一个列向量vT=(v1,v2,...,vn),则其二者的卷积定义为:
u∗v=v u=⎝⎜⎜⎜⎜⎜⎜⎜⎛v1v2...vn⎠⎟⎟⎟⎟⎟⎟⎟⎞∗(u1,u2,...,um)=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛v1u1v2u1v3u1...vnu1v1u2v2u2v3u2...vnu2v1u3v2u3v3u3...vnu3.......... . ....v1umv2umv3um...vnum⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞=An×m
并且,当且仅当矩阵An×m的秩r(A)=1时,滤波器才是可分离的滤波器。Gaussian滤波器和Sobel滤波器就是这种可分离的滤波器。
利用这个特性,对于二维高斯滤波器h(x,y)而言,我们将其分离成两个一维滤波器。对图像的二维卷积运算从而简化为对图像的两次一维卷积,具体如下所示:
h(x,y)(f∗h)(x,y)=(hx∗hy)(x)=f∗(hx∗hy)=(f∗hx)∗fy
同时,利用如上的特性,我们还可以利用一维高斯滤波器的结果生成二维高斯滤波器,代码如下所示:
1 2 3 4 5 6 7 8
| def gaussian_kernel_2d_acc(self): if self.width == 1: self.kernel = np.ones((1, 1)) return self.gaussian_kernel_1d() k = self.kernel self.kernel = k.reshape(self.width,1) * k.reshape(1,self.width)
|
更详细的代码可以参考高斯滤波器的生成。
参考文献
[1]: 图像处理、分析与机器视觉(第4版)
[2]: 如何通俗易懂的解释卷积?
[3]: 高斯模糊的算法
[4]: separable filter
[5]: Karas Pavel and Svoboda David (January 16th 2013). Algorithms for Efficient Computation of Convolution, Design and Architectures for Digital Signal Processing, Gustavo Ruiz and Juan A. Michell, IntechOpen, DOI: 10.5772/51942. Available from: https://www.intechopen.com/books/design-and-architectures-for-digital-signal-processing/algorithms-for-efficient-computation-of-convolution