原文:http://blog.csdn.net/baimafujinji/article/details/73302911

有一个说法:好奇心和懒惰是推动人类发明创造的两大动力!所以今天我又再次展现了我的好奇心。何况”我的眼里为什么常含着泪水,因为我有一个算法不会。“ 为了节约一点泪水,还是应该把一些算法搞清楚。

如果说让你对一幅含有噪声的图像进行去噪,你会想到什么最原始、最简单的、教科书上就会讲到的方法。我猜或许应该是Box Filter(也称均值滤波)或者Gaussian Filter,关于Box Filter可以参考本博主之间的一篇文章(文章链接)。但是无论Box Filter还是Gaussian Filter,它们的一个共有的不足就在于对待噪声和图像的纹理细节都采用一视同仁的处理方式,结果导致噪声被去掉的同时,图像的纹理和细节也会被一同磨平。这个Side effect是我们所不想见到的!

于是,几乎所有真正有价值的图像降噪方法都在试图让程序可以自适应地区隔无用的噪声和有用的图像纹理细节,然后再采取不同的处理方式,从而实现details preserving(或者edge preserving)。而且这样的方法还特别特别多,例如比较有名的双边滤波、基于PM方程的各向异性扩散滤波,以及基于TV-norm的去噪方法等等。关于这些内容你也可以参考《图像处理中的数学修炼》一书。在实际中,这些算法都具有非常广泛而重要的用途,例如医学影像处理中常常需要利用数字图像处理的技术对X-ray或者MRI图像等进行降噪,再比如现在手机中比较popular的美颜嫩肤都要以上面提到的那些details preserving的denoise算法。但是,上面提到的那些算法动辄就要用到像偏微分方程或者欧拉-拉格朗日方程等深奥晦涩的数学知识。我们能不能从一个比较简单的方法入手来一窥details preserving的denoise算法的能力和效果呢?这个可以有!


为什么开篇会提到好奇心这个问题呢?因为之前使用MATLAB时都知道其中的图像处理工具箱提供了一个wiener2函数,可以对图像进行降噪。从名字上看来它应该是利用了维纳滤波器来进行降噪的。但具体说它到底是怎么进行去噪的恐怕就很难说得清楚了。所以本文的源起也就是作者设法检视了一下MATLAB中的wiener2函数背后到底搞得什么鬼。例如上面是一张土星照片的局部图像。我们首先向其中加入一些高斯噪声(如下图左所示),然后再利用wiener2函数来对其进行降噪。效果如下图右所示。

可见原图像的纹理(例如图形环和远处的星辰等)都得到了很好的保护,而噪声也得到了有效的降低。但问题又回来了,wiener2函数到底是如何做到这一切的,其背后的原理是什么呢?

我们引入经典教科书中都会使用的一个图像退化模型,并以此作为算法讨论的开始。如下图所示,输入待处理图像f(x,y)在退化函数H的作用下,由于受到噪声η(x,y)的影响,最终得到一个退化图像g(x,y)。图像复原的过程就是在给定g(x,y)以及关于退化函数H和加性噪声η(x,y)的一些信息后,设法估计出原始图像的近似值f̂ (x,y)。当然,我们期望最终的近似值可以最大限度地逼近原始图像。显然关于H和η的信息掌握得越多,那么最终得到的估计结果就越接近原始图像。

如果H是一个线性移不变系统,那么在时域中给出的退化过程可由如下公式给出:

g(x,y)=h(x,y)∗f(x,y)+η(x,y)

其中, h(x,y)是退化函数在时域下的表示,运算符 ∗表示时域卷积。由卷积定理可知,时域上的卷积等同于频域上的乘积,所以上式在频域中的表述如下:

G(u,v)=H(u,v)F(u,v)+N(u,v)

其中的大写字母项是之前公式里对应项的傅里叶变换。

退化函数 H通常是指模糊、抖动等影响,因为本文主要讨论降噪方法,于是处理对象仅仅是在噪声 η的作用下受到污染的图像,所以现在的图像退化公式可以简化为:

g(x,y)=f(x,y)+η(x,y)

此时,(相比于普通的Box Filter或者Gaussian Filter)一个更好的降噪方法被称为Adaptive Filter,它的公式为:

f̂ (x,y)=g(x,y)−σ2gσ̂ 2L[g(x,y)−μ̂ L]

其中, σ2g是整张图像 g中的噪声方差, μ̂ L是点 (x,y)附近的(一个窗口内)的像素灰度均值, σ̂ 2L是点 (x,y)附近的(一个窗口内)的像素灰度的方差。其实你大概可以看出Adaptive Filter是用等式右端后面的一整项来作为(未知的)加性噪声的估计。那如何解释这样做的道理呢?我们可以从如下几个方面来考虑:

  • 如果σ2g=0,即整幅图像的噪声方差为零,其实也就相当于噪声为0,而此时公式表示f̂ (x,y)=g(x,y),恰好符合。
  • 如果σ̂ 2L>>σ2g,这其实暗示这个局部包含的图像边缘、纹理、细节较多(因为大于整体噪声方差),而这部分内容是应该被保护的。此时公式变为f̂ (x,y)=g(x,y),也就表示不需要做过多处理,也符合我们details preserving的需求。
  • 如果σ̂ 2L≈σ2g,则有f̂ (x,y)=μ̂ L,这表明(x,y)处在一个普通的区域,此时便可以应用普通的均值滤波来做处理。

当然,上面这个算法其实还有一个地方是需要我们加以应对的,那就是我们需要估计σ2g。在wiener2函数的实现过程中,具体做法是:点(x,y)处的局部均值为

μL=1MN∑(x,y)∈Wg(x,y)

局部方差为

σ2L=1MN∑(x,y)∈Wg2(x,y)−μ2L

其中 W是一个大小为 N×M的图像 g中点 (x,y)邻域窗口。然后算法创造一个使用这些估计值的逐像素的维纳滤波器:

f̂ (x,y)=μL+σ2L−v2σ2L[g(x,y)−μL]

其中, v2是整体噪声的方差,即 σ2g。If the noise variance is not given, here we use the average of all the estimated variances。如果你对维纳滤波器还不是很清楚也完全没有关系,因为前面的推导中其实已经得到我们现在需要的结果了。对上述等式的右侧做一些变量名替换,并进行简单的代数运算,可得:

μL+σ2L−v2σ2L[g(x,y)−μL]=μ̂ L+[g(x,y)−μ̂ L]−σ2gσ̂ 2L[g(x,y)−μL]=g(x,y)−σ2gσ̂ 2L[g(x,y)−μL]

于是便得到了之前一模一样的结果。

这个方法看起来如此的简单,它真的能按照我们预期的那样工作吗?下面就在MATLAB中编程实现这个算法。

function [f,noise] = mywiener2(g, nhood, noise)if (nargin<3)noise = [];
end% Estimate the local mean of f.
localMean = filter2(ones(nhood), g) / prod(nhood);% Estimate of the local variance of f.
localVar = filter2(ones(nhood), g.^2) / prod(nhood) - localMean.^2;% Estimate the noise power if necessary.
if (isempty(noise))noise = mean2(localVar);
end% Compute result
% f = localMean + (max(0, localVar - noise) ./ ...
%           max(localVar, noise)) .* (g - localMean);
%
% Computation is split up to minimize use of memory for temp arrays.
f = g - localMean;
g = localVar - noise;
g = max(g, 0);f = localMean + ((f ./ max(localVar, noise)) .* g);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

下面来试验一下上面这个看起来只有聊聊几行的简单函数是否可以实现保持图像细节的去噪功能。下面的MATLAB代码调用了上述函数,执行下面的代码将得到本文最开始所展示出来的效果图,而且这与直接调用wiener2函数所得之结果也是完全一致的。

RGB = imread('saturn.png');
I = rgb2gray(RGB);
I = I(601:1000,1:600);J = imnoise(I,'gaussian',0,0.005);
J = im2double(J);K = mywiener2(J,[5 5]);figure;
imshow(I), title('original image');figure;
subplot(1,2,1), subimage(J), title('noised image');
subplot(1,2,2), subimage(K), title('denoised image');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

更多图像处理中的数学问题请参考《图像处理中的数学修炼》,也欢迎广大读者到图像处理书籍读者群中参与讨论学习,并交流关于图像去噪算法和PDE图像处理算法的研究心得。

自适应图像降噪滤波器的设计与实现相关推荐

  1. 【OpenCV 例程200篇】100. 自适应局部降噪滤波器

    [OpenCV 例程200篇]100. 自适应局部降噪滤波器 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 3.7 ...

  2. 第5章 Python 数字图像处理(DIP) - 图像复原与重建11 - 空间滤波 - 自适应滤波器 - 自适应局部降噪、自适应中值滤波器

    标题 自适应滤波器 自适应局部降噪滤波器 自适应中值滤波器 自适应滤波器 自适应局部降噪滤波器 均值是计算平均值的区域上的平均灰度,方差是该区域上的图像对比度 g(x,y)g(x, y)g(x,y)噪 ...

  3. 可复现的图像降噪算法总结——超赞整理

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:AI算法与图像处理 图像降噪,是最简单也是最基础的图像处 ...

  4. 「技术综述」一文道尽传统图像降噪方法

    https://www.toutiao.com/a6713171323893318151/ 作者 | 黄小邪/言有三 编辑 | 黄小邪/言有三 图像预处理算法的好坏直接关系到后续图像处理的效果,如图像 ...

  5. 图像降噪算法——DnCNN / FFDNet / CBDNet / RIDNet / PMRID / SID

    图像降噪算法--DnCNN / FFDNet / CBDNet / RIDNet / PMRID / SID 图像降噪算法--DnCNN / FFDNet / CBDNet / RIDNet / PM ...

  6. 图像降噪算法——高斯低通滤波

    图像降噪算法--高斯低通滤波 图像降噪算法--高斯低通滤波 1. 基本原理 2. C++代码实现 3. 结论 图像降噪算法--高斯低通滤波 1. 基本原理 通过离散傅里叶变换对图像进行滤波流程作非常简 ...

  7. 图像降噪算法——中值滤波/均值滤波/高斯滤波/双边滤波

    图像降噪算法--中值滤波/均值滤波/高斯滤波/双边滤波 图像降噪算法--中值滤波/均值滤波/高斯滤波/双边滤波 1. 基本原理 2. C++代码实现 3. 结论 图像降噪算法--中值滤波/均值滤波/高 ...

  8. 固定系数与自适应结合的主动降噪耳机设计实验

    固定系数与自适应结合的主动降噪耳机设计实验 一.实验目的 完成前馈固定系数与自适应算法相结合的主动降噪耳机的设计,并分析该系统的性能:探究在固定系数算法工作前提下,自适应算法对耳机降噪性能的提升能力. ...

  9. matlab形态学降噪,基于MATLAB的荧光分子图像降噪方法

    基于MATLAB的荧光分子图像降噪方法 [摘要]:医学成像是一种身体内部的视觉显示的技术,用于临床分析和医学干预.其目它旨在揭示身体的内部结构,以便进行诊断和治疗.医学成像产生了大量数据,可形成常规解 ...

最新文章

  1. 看人装X,我就来气,开启极限装X模式
  2. 【转】Java里如何实现线程间通信
  3. 算法导论学习笔记 第2章 算法基础
  4. springAop和AspectJ的关系
  5. Unity基础知识学习笔记二
  6. MaxCompute JOIN优化小结
  7. 用python计算绩点的代码_【Python】计算GPA
  8. Android 6.0 Permission权限与安全机制
  9. win10开机黑屏时间长或只有鼠标解决办法,亲测可用
  10. python打开xls文件报错_python处理excel文件(xls和xlsx)
  11. Spring Boot+redis存储session,满足集群部署、分布式系统的session共享
  12. 文本对比,文本差异并排对比显示实现
  13. 微信小程序完整精品demo:移动小商城:基于node,包含前后台
  14. 1026. 多米诺和三格骨牌铺瓦问题
  15. matlab使用linprog()函数解决简单的线性规划问题
  16. 幼师计算机应用基础的认识200字,《计算机应用基础》课程教学与学前教育专业的深度融合...
  17. matlab 色温图,技术:图文教你了解色温及如何选择色温
  18. 电商申请mcn机构要什么条件
  19. Stata分享:一个在线-Stata-教程网站
  20. div自定义设置滚动条样式

热门文章

  1. linux 编程之库的使用(学习笔记)
  2. 学生计算机屏幕坏了怎么办,如果计算机显示器的屏幕坏了怎么办?
  3. 计算机基础办公应用考试试题,计算机基础考试试题库和答案.doc
  4. 2018批量打印开关_新品上市,震撼来袭!买UV平板打印机,一定看过这款后再定!...
  5. 赛马问题,毒药问题,倒水问题等智力题
  6. php打印文件目录结构,php和java关于目录树(列出某一目录下文件结构)
  7. 约翰诺曼超级计算机研究中心,第433章 拉泽尔松教授的决定
  8. 计算机实验11公式与函数,《大学计算机基础》实验报告十一——Excel2003公式与函数的应用.doc...
  9. 如何设计 QQ、微信、微博、Github 等第三方账号登陆 ?(附表设计)
  10. Java延迟加载的最佳实践应用示例!