最近稍微研究了下 canvas 滤镜在 OpenLayers 中的应用,发现自己照猫画虎可以做出滤镜效果,但是最关键的 kernel
这个卷积核
却一点都不了解,参考wiki深入学习一下写一篇笔记。
简介
卷积核
(kernel
),也叫卷积矩阵
(convolution matrix
)或者掩膜
(mask
),本质上是一个非常小的矩阵,最常用的是 3×3
矩阵。主要是利用核与图像之间进行卷积运算来实现图像处理,能做出模糊、锐化、凹凸、边缘检测等效果。
卷积运算
卷积
在通俗上理解是把原始矩阵中的每一个元素,都与其相邻的元素根据卷积核
的权重分布
做加权平均
,卷积运算的公式如下:
其中,g(x,y)
是被处理后的矩阵,w
是卷积核,f(x,y)
是原始矩阵,-a≤s≤a
并且 -b≤t≤b
。
以下示例就是卷积的通俗理解,第一个矩阵是卷积核
(其中的每个元素都是权重
),第二个矩阵是被处理的矩阵
,这里的*并不是真正矩阵运算中的*,而是将卷积核中的行和列都反转
再*,将计算得到的加权结果赋值给[2, 2]
位置处,一次运算就完成了。
用一张图片更容易说明这个过程:
将一个比较大的原始矩阵的每一个位置处
都根据核进行上述的运算,就得到整个原始矩阵的加权平均结果,也就是原始矩阵卷积运算后的结果。
将卷积运算应用到图像矩阵
对于一个普通的 8 位 RGB 位图
来举例,是由像素点矩阵
组成的,每个像素点都有 r(red)、g(green)、b(blue)
三个属性,每个属性的区间为[0, 2^8-1]
也就是[0, 255]
。
所以对于 r、g、b
任何一个通道来说,都是一个单纯的 xSize × ySize
的矩阵(xSize
、ySize
是图片的横向和纵向的像素点数
),就可以使用 kernel 卷积核
对其进行全图卷积运算
,实现图像的滤镜处理效果,如下所示:
以下示例中图片来自维基百科wiki,原图如下所示:
恒等(Identity)
identity 恒等卷积核
如下所示,
$$
\left[
\begin{matrix}
0 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 0 \\
\end{matrix}
\right]
$$
在 identity 卷积核
中,只有中心位置[2, 2]
位置处的权重为 1
,其余均为 0
,所以在进行卷积运算加权后时,像素只与自己本身位置进行了运算,最后返回的还是原像素的值,所以图像处理后是不变
的。
边缘检测(Edge detection)
edge detction(边缘检测)
对图像识别中的特征提取是非常有作用的,边缘检测卷积核都有一个共同点,就是能够突出图片矩阵中变化剧烈
的位置。矩阵如下所示,三种边缘检测核的效果是越来越明显,主要原因就是加强
了卷积核中[2, 2]
位置处与周围元素的区别
,图片中变化剧烈位置的在加权后,数值大的更大,数值小的更小,形成了边缘检测效果。
$$
\left[
\begin{matrix}
1 & 0 & -1 \\
0 & 0 & 0 \\
-1 & 0 & 1 \\
\end{matrix}
\right]
$$
$$
\left[
\begin{matrix}
0 & 1 & 0 \\
1 & -4 & 1 \\
0 & 1 & 0 \\
\end{matrix}
\right]
$$
$$
\left[
\begin{matrix}
-1 & -1 & -1 \\
-1 & 8 & -1 \\
-1 & -1 & -1 \\
\end{matrix}
\right]
$$
比对三个核,第一个核中的权重左上往右下
都是 1、0、1
,而右上往左下
是-1、0、-1
,在进行卷积运算时,对角方向
的边缘更容易识别出来;第二个核中,权重从左往右
是 1、-4、1
,从上往下
也是 1、-4、1
,所以水平和垂直
方向的边缘更容易识别出来;第三个核中权重水平垂直和对角
都是-1、8、-1
,所以水平和倾斜
的边缘都容易识别。
锐化(Sharpen)
锐化的本质还是利用的边缘检测的原理,放大[2, 2]位置
与周围元素的权重的区别。与边缘检测权重和为 0
相比,锐化卷积核中所有权重加起来后的值为 1
。当权重和大于 1
时,会整体使图片变亮
,小于 1
会变暗
,等于 1
就会保留原始亮度
,所以锐化卷积核保留了原始图形的亮度,而上述的三个边缘检测核使图像变暗。
$$
\left[
\begin{matrix}
0 & -1 & 0 \\
-1 & 5 & -1 \\
0 & -1 & 0 \\
\end{matrix}
\right]
$$
盒模糊(Box blur)
在盒模糊卷积核中,所有位置的权重均为 1/9
,所以[2, 2]位置处
的元素值会以一个相同权重
与周围变得更相似
,达到均匀模糊
的效果
$$
\frac{1}{9}
\left[
\begin{matrix}
1 & 1 & 1 \\
1 & 1 & 1 \\
1 & 1 & 1 \\
\end{matrix}
\right]
$$
高斯模糊(Gaussian blur)
高斯模糊卷积核
依赖的是高斯函数
,所以卷积核的值是围绕着中心点
分布的,离中心点越近,贡献也就越大,所以权重值就越高,二维区域高斯曲线图
如下:
3×3
首先列出一个 3×3
的高斯模糊卷积核,中心点
权重为 4
,离得最近的上下左右
权重都是 2
,稍远一点的对角位置
贡献的权重都是 1
,最后除以权重和 16
,矩阵和效果如下所示:
$$
\frac{1}{16}
\left[
\begin{matrix}
1 & 2 & 1 \\
2 & 4 & 2 \\
1 & 2 & 1 \\
\end{matrix}
\right]
$$
可以发现,因为权重更加聚焦
到中心点
位置,高斯模糊的效果相比盒模糊要更清晰一些。
5×5
再列出 5×5
的高斯模糊卷积核,和 3×3
类似,以中心点画圆
,离圆心越远
权重越小
,最后除以权重和 256
,矩阵和效果图如下:
$$
\frac{1}{256}
\left[
\begin{matrix}
1 & 4 & 6 & 4 & 1 \\
4 & 16 & 24 & 16 & 4 \\
6 & 24 & 36 & 24 & 6 \\
4 & 16 & 24 & 16 & 4 \\
1 & 4 & 6 & 4 & 1 \\
\end{matrix}
\right]
$$
与 3×3
的高斯模糊对比,由于距离中心点更远
的位置也贡献了权重
,所以 5×5
要更模糊一些。
反锐化掩膜(Unsharp masking)
反锐化掩膜
与 5 阶高斯模糊
的卷积核,所有位置都取相反数
,中间位置取值 476(-36+256+256)
,其实还是达到一种锐化
的效果,卷积核如下所示:
$$
-\frac{1}{256}
\left[
\begin{matrix}
1 & 4 & 6 & 4 & 1 \\
4 & 16 & 24 & 16 & 4 \\
6 & 24 & -476 & 24 & 6 \\
4 & 16 & 24 & 16 & 4 \\
1 & 4 & 6 & 4 & 1 \\
\end{matrix}
\right]
$$
实现原理如下图所示:
- 第一步:正常的
原始信号
,在本文中也就是原始图像矩阵
。 - 第二步:进行
模糊
处理,本文中进行5 阶高斯模糊
。 - 第三步:使用原始信号
减去
模糊后的信号,取得差值
,本文中就是36
。 - 第四步:给原始信号
反向
加上差值
,本文中就是-36+256+256
,完成了对原始图像的锐化
。
总结
无限感慨,对不起王老师,对不起曾老师!这就是本科不认真学数字信号处理
、硕士一知半解的处理物探数据
的下场。竟然等工作以后才明白,这里的卷积核不就是滤波器吗!研究前端竟然研究到地球物理头上去了 T.T!