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

设计不同的滤波器,可以达到去噪(denoising)、平滑(smoothing)、模糊(blurring)、锐化(sharpening)、浮雕(embossing)、边缘检测(edge detection)等目的。在空域中直接进行卷积操作(滑动窗口),需要4层循环嵌套,复杂度达到\(O(m^2*n^2)\),\(m\)为图像尺寸,\(n\)为滤波器尺寸,随着图像或卷积尺寸增大,复杂度以平方快速增长,因此需要一些快速实现方式,尤其是在计算资源并不充足的嵌入式等端上。
Box Blur
均值滤波器可能是最基本最常见的滤波器了,一个3*3的均值滤波器如1所示,使用该滤波器对图像进行滤波,相当于对图像中的每一个像素使用其周围的像素进行平均。均值滤波器用途广泛,除最直接的平滑操作外,还可近似实现其他滤波操作,比如带通滤波和高斯平滑等。因为均值滤波器在频域近似为一个低通滤波器,因此两个不同半径的均值滤波器滤波结果的差值可近似带通滤波器;根据中心极限定理,多次Box Blur的结果可近似高斯平滑。应用得越广泛就越需要仔细优化,可以采用均值滤波器来近似实现其他滤波器的一个前提就是均值滤波可以更高效。
\[
\frac{1}{9}
\left[
\begin{matrix}
1 & 1 & 1 \\
1 & 1 & 1 \\
1 & 1 & 1
\end{matrix}
\right] \tag{1}
\]
直接实现四层循环的均值滤波复杂度为\(O(m^2*n^2)\),可以利用均值滤波器所有权重都相同等性质实现快速滤波。
行列分解实现
可将卷积核分解为列向量和行向量的相乘,如2所示,对图像进行2D的均值滤波,等价于先逐行进行平均然后逐列平均,复杂度可由\(O(m^2*n^2)\) 降至\(O(m^2*2n)\) 。这样实现的前提是卷积核可分解,换句话说,可分解的卷积核均可考虑这样优化,比如高斯滤波等。
\[
\frac{1}{9}
\left[
\begin{matrix}
1 & 1 & 1 \\
1 & 1 & 1 \\
1 & 1 & 1
\end{matrix}
\right] = \frac{1}{3}
\left[
\begin{matrix}
1 \\
1 \\
1
\end{matrix}
\right]
\cdot
\frac{1}{3}
\left[
\begin{matrix}
1 & 1 & 1 \\
\end{matrix}
\right] \tag{2}
\]
类“队列”实现
行列分解后,相当于在行上和列上进行1D滑动窗口均值滤波。在1D窗口滑动过程中,相邻窗口有大量元素是重叠的,比如下图中,8、5、10和5、10、7其中5和10就是重叠的。整个滑动过程可以看成是不断进出“队列”的过程,窗口每向右移动1个像素,相当于最左侧的像素出队列,最右侧的像素进队列,当前像素的滤波结果为当前队列内元素之和然后平均,而前后一直驻留在队列中的元素则不需要重复加和,通过避免重复计算来实现提速。

因此,计算第\(i+1\) 个窗口的和\(S[i+1]\)可以通过第\(i\) 个窗口的和\(S[i]\)与最左\(x[i-r]\)最右\(x[i+r+1\)的元素得到,\(r\) 为滤波器半径,如下:
\[S[i+1] = S[i] + x[i+r+1] - x[i-r]\]
这样,我们得到了与滤波器尺寸无关的算法,算法复杂度进一步降低至\(O(m^2)\) 。
此外,我们也可考虑2D的滑动窗口,如下图所示:

同样利用相邻滑动窗口内的重叠元素,计算以元素\((i, j)\) 为中心的窗口元素之和\(S[i, j]\) 如下,其中\(C[i, j]\)为窗口内以\((i, j)\)为中心的半径为\(r\)的列和,
\[S[i, j] = \sum_{k=-r}^{+r} C[i, j+k]\]
窗口向右移动时,
\[S[i, j+1] = S[i, j] + C[i, j+r+1] - C[i, j- r]\]
窗口向下移动时,
\[C[i+1, j] = C[i, j] + C[i+r+1, j] - C[i-r-1, j]\]
滤波结果为:
\[x'[i, j] = \frac{1}{(2r+1)^2} S[i, j]\]
积分图
如果需要得到多个不同半径的均值滤波结果时,使用积分图(Summed-area table)可能是个好办法。积分图中\((x, y)\) 位置\(I(x, y)\)的值等于原图中该位置左上角所有像素之和,累加和包不包含这个像素自身所在的行和列与具体实现有关,这里沿用Wiki上的表述方式包含(Opencv为不包含),计算方式如下:
\[I(x, y) = \sum_{x'\le x, \ y' \le y}i(x', y')\]
积分图可通过单趟遍历快速实现,有了积分图就可以计算任意尺寸box内元素之和,仅需2次减法和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的速度的五倍)
滤波器——BoxBlur均值滤波及其快速实现的更多相关文章
- 学习 opencv---(7) 线性邻域滤波专场:方框滤波,均值滤波,高斯滤波
本篇文章中,我们一起仔细探讨了OpenCV图像处理技术中比较热门的图像滤波操作.图像滤波系列文章浅墨准备花两次更新的时间来讲,此为上篇,为大家剖析了"方框滤波","均值滤 ...
- 基础图像处理之混合空间增强——(Java:拉普拉斯锐化、Sobel边缘检测、均值滤波、伽马变换)
相信看过冈萨雷斯第三版数字图像处理的童鞋都知道,里面涉及到了很多的基础图像处理的算法,今天,就专门借用其中一个混合空间增强的案例,来将常见的几种图像处理算法集合起来,看能发生什么样的化学反应 首先,通 ...
- java实现中值滤波均值滤波拉普拉斯滤波
目录 来对下面的图像滤波,其实就是对各个像素点进行数学运算的过程 均值滤波 中值滤波 拉普拉斯滤波 Sobel滤波 注意 来对下面的图像滤波,其实就是对各个像素点进行数学运算的过程 均值滤波 均值滤波 ...
- 图像处理之均值滤波介绍及C算法实现
1 均值滤波介绍 滤波是滤波是将信号中特定波段频率滤除的操作,是从含有干扰的接收信号中提取有用信号的一种技术. 均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临 ...
- opencv —— boxFilter、blur、GaussianBlur、medianBlur、bilateralFilter 线性滤波(方框滤波、均值滤波、高斯滤波)与非线性滤波(中值滤波、双边滤波)
图像滤波,指在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像与处理中不可缺少的操作. 邻域算子,指利用给定像素及其周围的像素值,决定此像素的最终输出值的一种算子.线性邻域滤波器就是一种常 ...
- opencv-10-图像滤波-噪声添加与均值滤波-含opencv C++ 代码实现
开始之前 再说上一篇文章中, 我们想按照噪声产生, 然后将降噪的, 但是限于篇幅, 我就放在这一篇里面了, 说起图像的噪声问题就又回到了我们上一章的内容, 把噪声当作信号处理, 实际上数字图像处理实际 ...
- OpenCV计算机视觉学习(4)——图像平滑处理(均值滤波,高斯滤波,中值滤波,双边滤波)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice &q ...
- opencv实现图像邻域均值滤波、中值滤波、高斯滤波
void CCVMFCView::OnBlurSmooth()//邻域均值滤波 { IplImage* in; in = workImg; IplImage* out = cvCreateImage( ...
- 基于FPGA的均值滤波算法的实现
前面实现了基于FPGA的彩色图像转灰度处理,减小了图像的体积,但是其中还是存在许多噪声,会影响图像的边缘检测,所以这一篇就要消除这些噪声,基于灰度图像进行图像的滤波处理,为图像的边缘检测做好夯实基础. ...
随机推荐
- nsq源码阅读笔记之nsqd(三)——diskQueue
diskQueue是backendQueue接口的一个实现.backendQueue的作用是在实现在内存go channel缓冲区满的情况下对消息的处理的对象. 除了diskQueue外还有dummy ...
- java.util.Date 与 java.sql.Date 之间的转换
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); String dateStr = sdf.for ...
- 下拉框选择selected
var id=$("#orderId").children('option:selected').val(); //selected选中项取值 var id=$('#orderId ...
- 记录遭遇挖矿程序kthrotlds的失败处理经历
1 发现问题 在腾讯云上购买了一个centos7的服务器,平时用来练手,偶尔也安装一些程序进行测试,上面安装了mysql和redis,前段时间数据库经常掉线,连不上,到腾讯云后台进行查看,通过服务器实 ...
- 前端笔记之Vue(一)初识SPA和Vue&webpack配置和vue安装&指令
一.单页面应用(SPA) 1.1 C/S到B/S页面架构的转变 C/S:客户端/服务器(Client/Server)架构的软件. C/S 软件的特点: ① 从window桌面双击打开 ② 更新的时候会 ...
- 一个比喻讲明Docker是什么
之前一直听运维的同事讲Docker,说弄个Docker镜像,打包些应用什么的,还有时不时地在一些帖子里见到过关于Docker的三言两语,然后自己也自我感觉良好的把它总结归纳了一下认为:"往D ...
- 一致性 Hash 算法的实际应用
前言 记得一年前分享过一篇<一致性 Hash 算法分析>,当时只是分析了这个算法的实现原理.解决了什么问题等. 但没有实际实现一个这样的算法,毕竟要加深印象还得自己撸一遍,于是本次就当前的 ...
- 深入理解es6-Promise对象
前言 在之前翻博客时,看到promise,又重读了一边,突然发现理解很浅,记的笔记也不是很好理解,又重新学习promise,加深理解,学以致用 在promise出来之前,js常用解决异 ...
- ASP.NET Core - 利用Windsor Castle实现通用注册
问题引入 在ASP.NET Core - 依赖注入这篇文章里面,我们知道了如何利用ASP.NET Core原生的容器来实现依赖注入的,那我们为什么要替换掉默认的 IoC容器呢?从ASP.NET Cor ...
- Oracle数据库升级注意事项
1 备份配置参数 数据库升级前的配置参数要备份,如PGA大小 这样数据库升级后还可以升级前的配置,而不至于使用安装升级时的默认配置 2 检查版本兼容 确认数据库升级后是否对生产环境上的代码有影响,如果 ...