高斯模糊原理
基本概念
二维高斯模糊,或者说高斯滤波,是图像处理中非常常见的操作。操作的核心是使用一个从高斯分布中采样得到的掩膜,或者叫核,和输入图片中的每个像素及其邻域进行计算,结果保存到输出图片中。假设高斯核窗口尺寸为,高斯分布的标准差为 ,则高斯核可以表示为矩阵的形式
由于高斯分布的概率密度函数的非零值区间主要集中在 内,所以为了保证选取的高斯核的完整性,一般取 。
说完了高斯核,该说高斯模糊的表达式了。设输入图片为 ,输出图片为 ,第 行第 列的数据表示为 和 ,则使用窗口大小为 ,标准差为 的高斯核计算后的结果为
可分离核形式实现
但是,注意到,高斯核的表达式是可分离的。下面为了表示方便,令
符合局部性原则的内存访问加速
下面来考虑上述方法在内存访问效率方面的问题。利用 和 计算 的过程中,内存访问都是连续的,都是从左到右的形式。但是在利用 和 计算 的过程中,取出每一列中的相邻数据,需要跨行。如果需要处理的图片宽度比较大,跨行访问数据可能会导致 Cache Miss,这是违反了内存访问局部性原则的。为了解决这一问题,利用 和 计算 的方法需要调整。
实际上,利用 和 计算 同样可以按行的方式计算。为了表述方便,以计算 的第
2 行(下标从 0 开始)为例,
在代码实现的时候,为了计算 ,初始化一个长度为
8 的浮点数行向量 ,令里面的值全等于零,然后用遍历行元素的方式进行如下计算
最后将 中的浮点数的值四舍五入赋值给 。这样就避免了内存访问跨行的问题。注意,为了满足内存访问的局部性,增加了内存使用量,多用了 。
对于边界行,按照镜像对称的方式选取相应行进行计算。比如,为了计算 ,初始化一个长度为
8 的浮点数行向量 ,令里面的值全等于零,然后用遍历行元素的方式进行如下计算
最后将 中的浮点数的值四舍五入赋值给 。
扩展与总结
本文中所讲述的高斯模糊的计算方法,可以扩展到任意尺寸可分离核的滤波的实现。
设输入数据为 , 行 列,滤波核为 , 行 列,使用 对 进行二维滤波的结果是 。而直接采用二维循环的原始计算方法,需要进行 次乘法计算和 次加法计算。计算的时间复杂度是 的。
如果 是可分离核,可以写成列向量 和行向量 相乘的形式,即 。那么在计算滤波结果 的时候,可以先用 对 进行行滤波计算,将计算结果保存到 中,计算 中的每一个数值需要 次乘法计算和 次加法计算。再使用 对 进行列滤波计算,得到最终结果 。在 的基础上计算 中的每一个数值需要 次乘法计算和 次加法计算。总的来说,根据 计算 中的一个数值,需要进行 次乘法计算和 次加法计算。计算的时间复杂度从 降至 。
列滤波的过程还可以考虑内存访问的局部性原则,以提高程序的运行效率。
可分离核的实现方法和列滤波的内存访问加速的实现方法,都需要消耗额外的内存,用空间复杂度的提高换取时间复杂度和效率的改进。