滤波器——BoxBlur均值滤波及其快速实现

2020-04-26 16:56:03 浏览数 (1)

动机:卷积核、滤波器、卷积、相关

在数字图像处理的语境里,图像一般是二维或三维的矩阵,卷积核(kernel)和滤波器(filter)通常指代同一事物,即对图像进行卷积或相关操作时使用的小矩阵,尺寸通常较小,常见的有3*3、5*5、7*7等。卷积操作相当于对滤波器旋转180度后的相关操作,如下图所示,但很多滤波器是中心对称的,而且两者运算上可以等价,所以很多时候不太区分。

设计不同的滤波器,可以达到去噪(denoising)、平滑(smoothing)、模糊(blurring)、锐化(sharpening)、浮雕(embossing)、边缘检测(edge detection)等目的。在空域中直接进行卷积操作(滑动

大,复杂度以平方快速增长,因此需要一些快速实现方式,尤其是在计算资源并不充足的嵌入式等端上。

Box Blur

均值滤波器可能是最基本最常见的滤波器了,一个3*3的均值滤波器如1所示,使用该滤波器对图像进行滤波,相当于对图像中的每一个像素使用其周围的像素进行平均。均值滤波器用途广泛,除最直接的平滑操作外,还可近似实现其他滤波操作,比如带通滤波高斯平滑等。因为均值滤波器在频域近似为一个低通滤波器,因此两个不同半径的均值滤波器滤波结果的差值可近似带通滤波器;根据中心极限定理,多次Box Blur的结果可近似高斯平滑。应用得越广泛就越需要仔细优化,可以采用均值滤波器来近似实现其他滤波器的一个前提就是均值滤波可以更高效。

行列分解实现

类“队列”实现

行列分解后,相当于在行上和列上进行1D滑动窗口均值滤波。在1D窗口滑动过程中,相邻窗口有大量元素是重叠的,比如下图中,8、5、10和5、10、7其中5和10就是重叠的。整个滑动过程可以看成是不断进出“队列”的过程,窗口每向右移动1个像素,相当于最左侧的像素出队列,最右侧的像素进队列,当前像素的滤波结果为当前队列内元素之和然后平均,而前后一直驻留在队列中的元素则不需要重复加和,通过避免重复计算来实现提速。

积分图

这样,当需要不同尺寸均的值滤波结果时,使用积分图的运算时间是一样的。

指令级优化

除了以上优化方法,还可采用指令级优化。对每一个像素位置求均值是在该像素的邻域范围内进行的,同一行上的像素位于连续的内存区域,对像素施加的都是近乎相同的操作——加法或减法,因此时宜采用SIMD指令,如MMX、SSE、AVX、NEON等,同时载入多个数据、同时对多个数据进行相同的操作,一些实现方式可参见 参考资料,这里不再详述。需要注意的是,指令级的优化意味着兼容性、可扩展性的损失,如果代码尚未稳定,则不建议采用

一些优缺点和总结

这里简单分析下各种方法的优缺点:

  • 类“队列”实现:不能实现in-place操作,如果内存空间不足,可缓存一个窗口高度图像宽度的内存块,在缓存块操作后再写回原图。
  • 积分图方法:需要较大的内存来存储积分图,好处是积分图仅需求取一次,后面所有尺寸的Box Blur均可使用,而且求各处的滤波结果互不依赖,方便并行化。

基本上所有的优化方式的出发点都是减少不必要的重复计算,本文所介绍的几种方法在其他滤波操作的优化中也常被采用。以上仅为算法思路介绍,具体实现时可能要进一步考虑内存访问的时间、边界处理等细节,不再赘述。

参考

  • Box Blur
  • Fast Image Convolutions
  • Tips & Tricks: Fast Image Filtering Algorithms
  • APPROXIMATING A GAUSSIAN USING A BOX FILTER
  • Filter primitive ‘feGaussianBlur’
  • SSE图像算法优化系列十三:超高速BoxBlur算法的实现和优化(Opencv的速度的五倍)

0 人点赞