转载

高斯模糊算法的 C++ 实现

2008 年在一个 PS 讨论群里,有网友不解 Photoshop 的高斯模糊中的半径是什么含义,因此当时我写了这篇文章:

对Photoshop高斯模糊滤镜的算法总结 ;

在那篇文章中,主要讲解了高斯模糊中的半径的含义,是二维正态分布的方差的平方根,并且给出了算法的理论描述。现在我又打算把该算法用 c++ 实现出来,于是有了下面的这个 DEMO。

起初我是按照算法理论直接实现,即使用了二维高斯模板,结果发现处理时间很长,对一个图片竟然能达到大约数分钟之久。这样肯定是不对的,所以我百度了一下,发现这个问题应该采用分别进行两次一维高斯模糊就可以了 [1] ,这样算法的时间复杂度的一个系数,就从 O( sigma ^2 ) 降低到了 O( sigma)。这样算法于是速度提高到了毫秒级。

在理论上,高斯模板是无边界和无限扩展的一个二维曲面,在实现时,就必须对这个曲面进行截断有限大的二维模板。为了提高算法速度,所以采用一维高斯模糊,即一个一维的模板。因此根据下图所示的正态分布:

高斯模糊算法的 C++ 实现

图1. 正态分布的贡献比

此图来自参考资料 [1],根据文中叙述,此图实际来源于 http://zh.wikipedia.org/wiki/File:Standard_deviation_diagram.svg 。可以看到,在 3 σ 以外的贡献比例非常小,为 0.1 %,因此我们截断模板时,对模板边界定义为 3 * σ;

二维高斯模板的计算公式是:

高斯模糊算法的 C++ 实现

下图给出了二维高斯模糊的可视化结果,可视化方法时,生成二维高斯模板,然后取缩放因子 f = 255 / 模板中心点的数据,把模板数据等比缩放,然后绘制成灰度图片,这样中心点的亮度提高到最亮。为了可视化,每个点被放到成一个更大的 8 * 8 或者 16 * 16 的单元格大小。

高斯模糊算法的 C++ 实现

左侧是 σ = 0.849 时的模板,其中心 3 * 3 的浮点数据为:

sigma = 0.849:  0.055 0.110 0.055 0.110 0.221 0.110 0.055 0.110 0.055

然后对图片分别进行两个方向的一维高斯模糊,即可。下图给出了原图分别进行两个方向的一维高斯模糊中间结果:

高斯模糊算法的 C++ 实现

我实现的 DEMO 的界面如下所示:

高斯模糊算法的 C++ 实现

通过点击菜单 - 可视化 - 二维高斯模板可以在右侧生成一个灰度图片,即二维高斯模板的可视化结果。

在下方有一个控制面板,上面可以选择高斯模糊的算法参数,高斯半径的意义和 Photoshop 中的半径意义相同,都是算法中的 σ。

算法参数中:

(1)支持多线程处理,根据我的观察,线程数设置为和 CPU 核心数相同是比较合适的。线程数比 CPU 核心数更多,也是没有什么意义的,因为算法执行时,CPU 已经满负荷运转了。开启更多线程,也不能再提高速度了。

开启多线程数量为 CPU 核心数相同时,假设核数为 p,则通常大约为单线程处理的 p 倍。

(2)浮点类型:支持 float 和 double。它是高斯模板的数据的类型,也是进行像素加权累加时的数据类型,根据我的观察,float 和 double 的速度相差不大。基本相同。

(3)高斯半径:即 σ。算法的常数系数为 O(σ)。很显然,σ 的值取得越大,算法耗时将会越长。

在 C++ 程序中,使用我写的这个算法是非常简单的,例如:

#include <GaussBlurFilter.hpp>  CGaussBlurFilter<double> _filter; _filter.SetSigma(3.5); //设置高斯半径 _filter.SetMultiThreads(true, 4); //开启多线程  //lpSrcBits/lpDestBits: 像素数据的起始地址,必须以 4 bytes 对齐 //bmWidth, bmHeight: 图像宽度和高度(像素) //bpp: 位深度,支持 8(灰度), 24(真彩色), 32 _filter.Filter(lpSrcBits, lpDestBits,     bmWidth, bmHeight, bpp);

需要注意的是,在多线程处理中,我使用了 Windows API (例如 CreateThread)等,这使得 GaussBlurFilter.hpp 目前只能用在 Windows 平台,如果要在其他平台使用,应当修改和多线程有关的 API 函数调用。

【相关下载】:

(1)Demo 的可执行文件(包含 GaussBlurFilter.hpp): GaussBlurDemo_Bin.zip

(2)Demo 的完整源码(包含可执行文件和 GaussBlurFilter.hpp):GaussBlur_Src.zip

【参考资料】

[1]. 高斯模糊算法的实现和优化;

[注] 文中的公式,采用如下网址生成: http://www.codecogs.com/latex/eqneditor.php

正文到此结束
Loading...