高斯模糊的算法

作者: 阮一峰

日期: 2012年11月14日

通常,图像处理软件会提供"模糊"(blur)滤镜,使图片产生模糊的效果。

"模糊"的算法有很多种,其中有一种叫做"高斯模糊"(Gaussian Blur)。它将正态分布(又名"高斯分布")用于图像处理。

本文介绍"高斯模糊"的算法,你会看到这是一个非常简单易懂的算法。本质上,它是一种数据平滑技术(data smoothing),适用于多个场合,图像处理恰好提供了一个直观的应用实例。

一、高斯模糊的原理

所谓"模糊",可以理解成每一个像素都取周边像素的平均值。

上图中,2是中间点,周边点都是1。

"中间点"取"周围点"的平均值,就会变成1。在数值上,这是一种"平滑化"。在图形上,就相当于产生"模糊"效果,"中间点"失去细节。

显然,计算平均值时,取值范围越大,"模糊效果"越强烈。

上面分别是原图、模糊半径3像素、模糊半径10像素的效果。模糊半径越大,图像就越模糊。从数值角度看,就是数值越平滑。

接下来的问题就是,既然每个点都要取周边像素的平均值,那么应该如何分配权重呢?

如果使用简单平均,显然不是很合理,因为图像都是连续的,越靠近的点关系越密切,越远离的点关系越疏远。因此,加权平均更合理,距离越近的点权重越大,距离越远的点权重越小。

二、正态分布的权重

正态分布显然是一种可取的权重分配模式。

在图形上,正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。

计算平均值的时候,我们只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。

三、高斯函数

上面的正态分布是一维的,图像都是二维的,所以我们需要二维的正态分布。

正态分布的密度函数叫做"高斯函数"(Gaussian function)。它的一维形式是:

其中,μ是x的均值,σ是x的方差。因为计算平均值的时候,中心点就是原点,所以μ等于0。

根据一维高斯函数,可以推导得到二维高斯函数:

有了这个函数 ,就可以计算每个点的权重了。

四、权重矩阵

假定中心点的坐标是(0,0),那么距离它最近的8个点的坐标如下:

更远的点以此类推。

为了计算权重矩阵,需要设定σ的值。假定σ=1.5,则模糊半径为1的权重矩阵如下:

这9个点的权重总和等于0.4787147,如果只计算这9个点的加权平均,还必须让它们的权重之和等于1,因此上面9个值还要分别除以0.4787147,得到最终的权重矩阵。

五、计算高斯模糊

有了权重矩阵,就可以计算高斯模糊的值了。

假设现有9个像素点,灰度值(0-255)如下:

每个点乘以自己的权重值:

得到

将这9个值加起来,就是中心点的高斯模糊的值。

对所有点重复这个过程,就得到了高斯模糊后的图像。如果原图是彩色图片,可以对RGB三个通道分别做高斯模糊。

六、边界点的处理

如果一个点处于边界,周边没有足够的点,怎么办?

一个变通方法,就是把已有的点拷贝到另一面的对应位置,模拟出完整的矩阵。

七、参考文献

* How to program a Gaussian Blur without using 3rd party libraries

(完)

留言(60条)

google、百度等搜索引擎用的以图搜图,就是这个工作原理吧。

引用huiris的发言:

google、百度等搜索引擎用的以图搜图,就是这个工作原理吧。

这也是一种算法,不过google貌似不是用这种方法,如果你一直关注阮一峰你会发现他以前讲过这个问题

引用huiris的发言:

google、百度等搜索引擎用的以图搜图,就是这个工作原理吧。

不是,那个是转为灰度图之类的。

每次看博主的科普文都感觉配图真漂亮啊……

引用iCyOMiK的发言:

不是,那个是转为灰度图之类的。

http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html

我也觉得配图太给了,能透露一下是用什么软件制作的图片吗?

阮老师,你的文章越来越合我的口味了,前段时间我也在弄这个,我想给图像加入高斯噪声,虽然程序实现了,但是原理还是模糊的,你这篇文章是讲得最浅显易懂的。

引用esay的发言:

我也觉得配图太给了,能透露一下是用什么软件制作的图片吗?

图像元信息里写的是 Photoshop CS 5。

这解释太好了,我之前看了半天维基百科,怎么就没看到最关键的正态分布呢?

上半部分说起来更像均值滤波吧

你真是高手啊,什么技术都能琢磨,

越靠近的点关系越密切,越远离的点关系越疏远。——反距离权重。

原来是这样子处理的啊,那视频里的动态模糊处理(打马赛克)是怎么弄的呢?

越来越技术控了。

很有帮助,谢谢~

阮老师,发现你这篇文章一个错字了:“显然,计算平均值时,取值范围最大,"模糊效果"越强烈。”
这个里面的“最大”,应该是“越大”

最近在做图像,在您这里有意想不到的收获,哈哈。

引用邓安良的发言:

阮老师,发现你这篇文章一个错字了:“显然,计算平均值时,取值范围最大,"模糊效果"越强烈。”
这个里面的“最大”,应该是“越大”

谢谢指出,已更正。

我了个去,通俗易懂,再接再力。。。加油,期待你的好文。

博主给力~~~

博主,你的几本书都买了,很喜欢你

博主,求介绍一下锐化的算法?感谢感谢

同族间的交往已经成为金钱交易的冠冕,看看你们周围,有几个能禁得住金钱诱惑的?官僚们一再强调罚钱并非是花钱买罪,但这只是在增添金钱的新功能而已,实际上你犯点‘小错’只要花点钱就OK,而且居然还叮嘱你不要向外宣传,这是我周围发生的事实,相信过不了多久花钱杀人会成为正当行为。但是不得不承认,官僚们的统治很‘成功’,几乎每个人都为了赚钱拼命‘努力’,达到了‘国家和平昌盛’的标准,虽然确切地说是‘官僚和平昌盛’。发在这里是因为这好像是最新更新文章。顺便说句我是学物理的。

我很好奇楼主到底能不能看到我的评论,我们可是一个级别的freethinker啊,看到赶紧吱个声。顺便说句我这网络有点问题电子邮件用不了。

这就是数字图像处理里的高斯低通滤波器吧。

怪不得 Photoshop 的 Gaussian Blur 需要设置 Radius 参数。

居然在这里找到想要的了。佩服博主,对图像算法都有这么细致的研究!

老师请问你怎么学学的这些的,能不能把你学习的教材名字发给我

最近在看一段高斯模糊的源码,因不了解此算法,理解有点生硬,百度到此,感谢楼主提供这么漂亮的讲解

你好,读完有一个问题:你说每一个像素点在高斯模糊时,都要以自己为中心,取周围点的值来进行加权平均,但是,周围点的值又要以自己为中心,取它自己周围像素点的值来平均。换句话说,周围像素点的值本身也相互依赖!而在文章中,你似乎是直接取周围点的像素值来进行计算的,这些值都是高斯模糊前的值,这个问题你怎么看?

请问一下卷积运算有没运算顺序?从左到右按行?算出的值直接替换还是放在新数组里?

引用norman的发言:

你好,读完有一个问题:你说每一个像素点在高斯模糊时,都要以自己为中心,取周围点的值来进行加权平均,但是,周围点的值又要以自己为中心,取它自己周围像素点的值来平均。换句话说,周围像素点的值本身也相互依赖!而在文章中,你似乎是直接取周围点的像素值来进行计算的,这些值都是高斯模糊前的值,这个问题你怎么看?

同问。能否再算一个临近点给大家看看?

引用norman的发言:

你好,读完有一个问题:你说每一个像素点在高斯模糊时,都要以自己为中心,取周围点的值来进行加权平均,但是,周围点的值又要以自己为中心,取它自己周围像素点的值来平均。换句话说,周围像素点的值本身也相互依赖!而在文章中,你似乎是直接取周围点的像素值来进行计算的,这些值都是高斯模糊前的值,这个问题你怎么看?

我想应该是,所有点的计算按照原始值计算,得出目标值后,最后一步一次性所有点全部替换,以目标值替换掉原始值。

可以拿列队做对比。一次列队的过程是(“成一列纵队”命令发出后):
1. 每个人都是先根据周围人的位置估算出自己的目标位置。
2. 在估值基础上各自同时移动,而不是等周围人动了之后才去估算自己应该怎么去对齐。
3. 根据对齐情况,每个人自行决定要不要重复步骤1和步骤2
步骤1和步骤2可以类比为进行一次“高斯模糊”


我用python实现了你的介绍。
具体代码在:http://blog.csdn.net/jkhere/article/details/9464701

一直没搞明白高斯的二维权值模板可以降成两个一维的模板,分别用一维模板处理的图像的效果与二维模板实现的效果是相同的。这个特性被称作分离性,可是对于文中所指出的二维模板,它分离出的一维模板是什么样子的呢?多谢赐教!

“其中,μ是x的均值,σ是x的方差。”,σ是标准差,不是方差

老师讲的真的是很好,不过那个函数里面的e是什么,自然对数吗?应该怎么算,教教我,谢谢。

好文!谢谢!

将这9个值加起来,就是中心点的高斯模糊的值.

是不是那个加权处理过了 不需要求平均值了?

引用demos的发言:

将这9个值加起来,就是中心点的高斯模糊的值.

是不是那个加权处理过了不需要求平均值了?

你的问题问的不太清楚,你想要求什么的平均值?

很好,多谢阮兄。以前对高斯模糊的“高斯”二字不理解现在终于理解了。

我是一个Photoshop软件爱好者,给图像处理专业人士提个建议:如果能灵活运用Photoshop这款软件将对你们有巨大的提升。因为虽然这款软件不告诉你具体的算法,但它处理图像的思路非常直观。

比如本文中最后提到的边界点的处理,Photoshop里面就有这种滤镜,它无疑可以扩展你的思路。

引用一米阳光的发言:

你的问题问的不太清楚,你想要求什么的平均值?

您好,我也有同样的问题,按照你之前说的一个3*3的图中,中心点的高斯模糊的值是周围八个点的值之和再求平均,但是在最后经过加权处理之后又说直接把九个值加起来就是中心点的高斯模糊值了。有点不解,求解答。

引用tanrui8765的发言:

一直没搞明白高斯的二维权值模板可以降成两个一维的模板,分别用一维模板处理的图像的效果与二维模板实现的效果是相同的。这个特性被称作分离性,可是对于文中所指出的二维模板,它分离出的一维模板是什么样子的呢?多谢赐教!

这个是利用了二维傅里叶变化的性质,按行变化以后,然后在此基础上,按列变化,不影响运算的结果。简而言之,这是利用其性质,降低了运算。

请问老师怎样理解下面一段话:
理论上,高斯分布在所有定义域上都有非负值,这就需要一个无限大的卷积核。实际上,仅需要取均值周围3倍标准差内的值,以外部份直接去掉即可。
因为我在论文中,有关基于高斯函数的距离标准差和灰度标准差的计算可以根据3sigma准则来确定,不是很明白,例如一个13*13的模板,求它的距离高斯函数,x,y为它的坐标,怎样求sigma?

这个网站真不错,国内像这样干净而有价值的网站太少了。(PS:我还是从百度百科的链接发现这个网站的,对百度的广告无语了)

受教了!谢谢你~

请问有没有javascript的开源代码实现高斯分布通用算法?

说明一下,二维正太分布,其实应该有μ1,μ2,σ1,σ2,ρ五个变量,这里是特殊情况,x,y独立ρ=0, μ1,μ2=0,σ1,σ2相等,才变成上述的形式。避免误解。。

发现博主解释的很清楚,果断继续关注,看完这一篇,顺便把神经网络也看一下!

讲的很通俗易懂,对于我这种想大致了解的,good参考资料.

有几张图失效了。

@bber01:

我想应该是,所有点的计算按照原始值计算,得出目标值后,最后一步一次性所有点全部替换,以目标值替换掉原始值。
这个解释给力!

引用慎独及梦的发言:

“其中,μ是x的均值,σ是x的方差。”,σ是标准差,不是方差

顶!

另外,其实感觉可以再多介绍一点关于σ的选择。
比如,为什么选择σ=1.5呢?什么依据?
以及σ越大表示什么,越小表示什么?

关于σ的选择我不太清楚

但σ越大表示模糊程度越大,其实σ越大反映到正太分布函数中就是,钟形曲线的“钟”越“矮胖”,所以邻域内除目标像素(x,y)以外的其他像素权重也相应提升,或者说所有像素的权重之间的差值变小。导致其他像素对目标像素(x,y)最终像素值的影响也变大,结果就是越模糊了。反之,“钟”就越“瘦高”,模糊程度越低。

那个符号是标准差,它的平方才是方差。。。

请问为什么高斯模糊权重合需要为1呢?
这样图像处理后画面应该会变暗才对,
后面又如何提高处理后的亮度会比较好?

请问一开始最简单的例子就是中间像素2变成1那个,既然后面灰度值加权计算的时候会算中间25的值,那一开始的例子为什么没有把2也算进去呢?假设例子中九宫格每个加权都一样,平均分配,那么最终中间的值应该为(2/9+8*1/9)=10/9=1.11。直接用周围的1去代替中间的2,意思能懂,但是原理上是不是就和后面灰度值计算的时候完全不同了呢?

如有错误,烦请指正。

博主,我这有几个图挂了,影响学习了,希望修复,麻烦了

引用Matthew的发言:

请问一开始最简单的例子就是中间像素2变成1那个,既然后面灰度值加权计算的时候会算中间25的值,那一开始的例子为什么没有把2也算进去呢?假设例子中九宫格每个加权都一样,平均分配,那么最终中间的值应该为(2/9+8*1/9)=10/9=1.11。直接用周围的1去代替中间的2,意思能懂,但是原理上是不是就和后面灰度值计算的时候完全不同了呢?

如有错误,烦请指正。

抛砖引玉,一开始图片模糊是采用中间像素值取周边像素值的平均值的方式进行计算,后来有了高斯模糊的方法,它用的滤波器产生的结果应该是(0*2/8+8*1/8)=8/8=1。

> 其中,μ是x的均值,σ是x的方差。因为计算平均值的时候,中心点就是原点,所以μ等于0。

第三节,高斯函数应该是 σ 是标准差, σ^2 是方差吧。

引用慎独及梦的发言:

“其中,μ是x的均值,σ是x的方差。”,σ是标准差,不是方差

说的对,我也发现这个问题

刚刚看到博主的文章,有两个不懂得地方
1、平均值用的是相邻半径内的平均值,这个是指原始图片的平均值?还是不断变换后的平均值
2、如果半径为5是不是在边缘地区5以内的点不发生任何变化,因为边缘5以内的不能取到完整的平均值了。

我要发表看法

«-必填

«-必填,不公开

«-我信任你,不会填写广告链接