本节所用图片素材共享于原始图片,提取码 523o
数字图形处理过程中引入噪声可分为两类,一类是由于经过系统引起的噪声,一类是由于干扰引起的加性噪声,当仅考虑加性噪声时,含有噪声的图像可表示:
g ( x , y ) = f ( x , y ) + η ( x , y ) (1) g(x, y)=f(x, y)+\eta(x,y) \tag{1} g(x,y)=f(x,y)+η(x,y)(1)
和DFT形式:
G ( u , v ) = F ( u , v ) + N ( u , v ) (2) G(u,v) = F(u, v) + N(u,v) \tag {2} G(u,v)=F(u,v)+N(u,v)(2)
对于这种形式的噪声,主要考虑空间域滤波。
为描述方便,后文中用 S x y S_{xy} Sxy表示 f ( x , y ) f(x,y) f(x,y)周围 m × n m \times n m×n邻域内的点的坐标的集合,那么,那么 ( s , t ) (s,t) (s,t)就表示该邻域内某一点的坐标, g ( s , t ) g(s,t) g(s,t)就表示该邻域内某一点的灰度值
算数均值滤波器
算数均值滤波是通过计算点 f ( x , y ) f(x,y) f(x,y)周围大小为 m × n m \times n m×n的邻域中像素灰度的算数平均值来完成的,即:
f ^ ( x , y ) = 1 m n ∑ ( s , t ) ∈ S x y g ( s , t ) (3) \hat f(x,y) = \frac{1}{mn} \sum_{(s,t) \in S_{xy}}g(s,t) \tag{3} f^(x,y)=mn1(s,t)∈Sxy∑g(s,t)(3)
显然,该滤波器可以通过如下方式实现:
filter = ones(m, n) / (m*n);
g = imfilter(f, filter, 'replicate');
不过,为了减少双精度浮点数计算的舍入误差,一般将将系数 1 m n \frac{1}{mn} mn1放在最后计算:
filter = ones(m, n);
g = imfilter(f, filter, 'replicate') / (m * n);
当然,图像处理工具箱中也提供了算数均值滤波器的实现:
filter = fspecial('average', [m, n]);
g = imfilter(f, filter, 'replicate');
实际中使用哪种都是可以的
几何均值滤波器
几何均值滤波是通过计算点 f ( x , y ) f(x,y) f(x,y)周围大小为 m × n m \times n m×n的邻域中像素灰度的几何平均值来完成的,即:
f ^ ( x , y ) = [ ∏ ( s , t ) ∈ S x y g ( s , t ) ] 1 m n (4) \hat f(x,y) =\left [ \prod_{(s,t) \in S_{xy}}g(s,t) \right ]^{\frac{1}{mn}} \tag{4} f^(x,y)=⎣⎡(s,t)∈Sxy∏g(s,t)⎦⎤mn1(4)
几何均值滤波器与算数均值滤波器相比,丢失的图像细节更少。
matlab中提供了计算几何均值的函数geomean(),故几何均值滤波可通过如下代码实现:
g = colfilt(f, [m, n], 'sliding', @geomean);
如下图(a)是一块8比特X射线图,图(b)显示了被均值为0,方差为400的加性高斯噪声污染的结果,图(c)和图(d)显示了使用大小为3x3的算数均值滤波和几何均值滤波的结果,显然这两种滤波器都衰减了噪声,几何均值滤波与算数均值滤波相比,图像模糊程度更小(注意例如图(c)和图(d)顶部连接片)。
本节所用完整代码如下
f = imread('Fig0507(a)(ckt-board-orig).tif');
figure
subplot(1, 2, 1);
imshow(f);
title('(a)原始图像');
f_with_noise = imread('Fig0507(b)(ckt-board-gauss-var-400).tif');
subplot(1, 2, 2);
imshow(f_with_noise);
title('(b)被均值为0,方差为400的加行高斯噪声污染的图像');
g_mean = colfilt(f_with_noise, [3, 3], 'sliding', @mean) / (3 * 3);
figure
subplot(1, 2, 1);
imshow(g_mean, [ ]);
title('(c)算数平均值滤波');
% 注意, geomean使用了进行了取对数加快运算,因此为了防止丢失精度和
% log0的出现,要将原图转为double类型并加上eps(matlab所能表示的最小的数)
g_geomean = colfilt(double(f_with_noise) + eps, [3, 3], 'sliding', @geomean);
subplot(1, 2, 2);
imshow(g_geomean, [ ]);
title('(d)几何平均值滤波');
谐波均值滤波器
谐波滤波器由如下式子给出:
f ^ ( x , y ) = m n ∑ ( s , t ) ∈ S x y 1 g ( s , t ) (5) \hat f(x,y) =\frac {mn}{\sum_{(s, t) \in S_{xy}} \frac {1}{g(s,t)}} \tag{5} f^(x,y)=∑(s,t)∈Sxyg(s,t)1mn(5)
谐波均值滤波器对于盐粒噪声(白点)效果较好,但不适用于胡椒噪声(暗点),也善于处理像高斯噪声那样的其他噪声
逆谐波均值滤波器
逆谐波均值滤波器由如下式子给出
f ^ ( x , y ) = ∑ ( s , t ) ∈ S x y g ( s , t ) Q + 1 ∑ ( s , t ) ∈ S x y g ( s , t ) Q (6) \hat f(x,y) =\frac {\sum_{(s, t) \in S_{xy}} g(s,t)^{Q+1} }{\sum_{(s, t) \in S_{xy}} g(s,t)^Q} \tag{6} f^(x,y)=∑(s,t)∈Sxyg(s,t)Q∑(s,t)∈Sxyg(s,t)Q+1(6)
其中Q为滤波器的阶数,这种滤波器适合消除椒盐噪声,当Q为正时,消除胡椒噪声;当Q为负时,消除盐粒噪声。当Q=0时,(6)式简化为一个算数均值滤波器,当Q = -1时,(6)简化为一个谐波均值滤波器。
根据逆谐波均值滤波器的定义,逆谐波均值滤波器可通过如下代码实现:
这里分母在计算完成后要加上eps防止分母为0的情形出现。
g = imfilter(f .^ (Q + 1), ones(m,n), 'replicate') ./ (imfilter(f .^ (Q), ones(m,n), 'replicate') + eps);
下图(a)和(c )显示了一幅被概率为0.1的胡椒噪声(a)和盐粒噪声(c )污染的图像,图(b)是对图(a)使用Q=1.5的逆谐波均值滤波器滤波的结果,图(d)是对图(c )使用Q = -1.5的逆谐波均值滤波器滤波的结果,可以看到在正确选择Q后,胡椒噪声与盐粒噪声均被消除。另外,逆谐波均值滤波器不能同时处理椒盐噪声,换言之,如果使用正Q处理盐粒噪声或负Q处理胡椒噪声,则会产生不可预估的后果,如图(e)(f)是使用Q=-1.5处理图(a)和Q=1.5处理图(c )的结果,显然,这两个都没有完成去噪的任务。
本节所用的完整代码如下:
f = imread('Fig0507(a)(ckt-board-orig).tif');
[M, N] = size(f);
n_pepper = imnoise2('salt & pepper', M, N, 0.1, 0);
c = find(n_pepper == 0);
f_pepper = f;
f_pepper(c) = 0;
figure
subplot(1, 2, 1)
imshow(f_pepper);
title('(a)被概率为0.1的胡椒噪声污染的图像')
g = contra_harmonic_mean(f_pepper, 3, 3, 1.5);
subplot(1, 2, 2)
imshow(g, [ ]);
title('(b)Q=1.5的逆谐波均值滤波结果');
n_salt = imnoise2('salt & pepper', M, N, 0, 0.1);
c = find(n_salt == 1);
f_salt = f;
f_salt(c) = 255;
figure
subplot(1, 2, 1)
imshow(f_salt);
title('(c)被概率为0.1的盐粒噪声污染的图像')
g = contra_harmonic_mean(f_salt, 3, 3, -1.5);
subplot(1, 2, 2)
imshow(g, [ ]);
title('(d)Q=-1.5的逆谐波均值滤波结果');
g = contra_harmonic_mean(f_pepper, 3, 3, -1.5);
figure
subplot(1, 2, 1)
imshow(g, [ ]);
title('(e)胡椒噪声经Q=1.5的逆谐波均值滤波器滤波结果');
g = contra_harmonic_mean(f_salt, 3, 3, 1.5);
subplot(1, 2, 2)
imshow(g, [ ]);
title('(f)盐粒噪声经Q=-1.5的逆谐波均值滤波器滤波结果');
function g = contra_harmonic_mean(f,m,n, Q)
f = double(f);
g = imfilter(f.^(Q+1), ones(m,n), 'replicate') ./ imfilter(f .^ (Q), ones(m,n), 'replicate') + eps;
end
综上,算数均值滤波器和几何均值滤波器适合处理高斯或均匀噪声,逆谐波均值滤波器适合处理脉冲噪声。
中值滤波器
中值滤波器由下式定义:
f ^ ( x , y ) = m e d i a n ( s , t ) ∈ S x y { g ( s , t ) } (7) \hat f(x,y) = \underset {(s,t) \in S_{xy}}{median} \{ g(s,t) \} \tag{7} f^(x,y)=(s,t)∈Sxymedian{g(s,t)}(7)
借助matlab提供的median函数,很容易得到中值滤波代码:
g = colfilt(f, [m, n], 'sliding', @median)
另外,matlab也提供了medfilt2函数,也可以用来进行中值滤波。
下图(a)显示了一幅被 P a = P b = 0.1 P_a=P_b=0.1 Pa=Pb=0.1的椒盐噪声污染的图像,图(b)(c)(d)是对图(a)分别使用3x3的中值滤波器进行一次、两次、三次中值滤波的结果,其结果对图(a)的改进十分明显。 本节所用代码如下:
f = imread('Fig0507(a)(ckt-board-orig).tif');
[M, N] = size(f);
n_s_p = imnoise2('salt & pepper', M, N, 0.1, 0.1);
f_s_p = f;
c = find(n_s_p == 0);
f_s_p(c) = 0;
c = find(n_s_p == 1);
f_s_p(c) = 255;
figure
subplot(2, 2, 1)
imshow(f_s_p, [ ]);
title('(a)Pa=Pb=0.1的椒盐噪声污染图像')
g1 = colfilt(f_s_p, [3, 3], 'sliding', @median);
subplot(2, 2, 2)
imshow(g1, [ ])
title('(b)图(a)一次中值滤波结果')
g2 = colfilt(g1, [3, 3], 'sliding', @median);
subplot(2, 2, 3)
imshow(g2, [ ])
title('(c)图(a)两次中值滤波结果')
g3 = colfilt(g2, [3, 3], 'sliding', @median);
subplot(2, 2, 4)
imshow(g3, [ ])
title('(d)图(a)三次中值滤波结果')
最大值和最小值滤波器
最大值滤波器由下式定义:
f ^ ( x , y ) = m a x ( s , t ) ∈ S x y { g ( s , t ) } (8) \hat f(x,y) = \underset {(s,t) \in S_{xy}}{max} \{ g(s,t) \} \tag{8} f^(x,y)=(s,t)∈Sxymax{g(s,t)}(8)
最大值滤波器对于发现图像中亮点非常有用,由于胡椒噪声灰度值非常低,所以最大值滤波器适合去除胡椒噪声
最小是滤波器由下式定义:
f ^ ( x , y ) = m a x ( s , t ) ∈ S x y { g ( s , t ) } (9) \hat f(x,y) = \underset {(s,t) \in S_{xy}}{max} \{ g(s,t) \} \tag{9} f^(x,y)=(s,t)∈Sxymax{g(s,t)}(9)
最小值滤波器对于发现图像中暗点非常有用,由于盐粒噪声灰度值非常高,所以最小值滤波器适合去除盐粒噪声
和上面一样,最大值和最小值滤波器可由以下代码得到:
g_max = colfilt(f, [m, n], 'sliding', @max);
g_min = colfilt(f, [m, n], 'sliding', @min);
同逆谐波均值滤波器一样,最大值滤波器和最小值滤波器都不能同时处理椒盐噪声,下图(a)显示了使用最大值滤波器对 P a = 0.1 P_a=0.1 Pa=0.1的胡椒噪声滤波的结果,图(b)显示了使用最小值滤波器对 P b = 0.1 P_b=0.1 Pb=0.1的盐粒噪声滤波的结果。
另外注意,最大值滤波器扩展了图像的白色边缘,使得图像整体亮度变大,而最小值滤波器扩展了图像的黑色边缘,使的图像的整体亮度变小。
f = imread('Fig0507(a)(ckt-board-orig).tif');
[M, N] = size(f);
n_pepper = imnoise2('salt & pepper', M, N, 0.1, 0);
f_pepper = f;
c = find(n_pepper == 0);
f_pepper(c) = 0;
g_max = colfilt(f_pepper, [3, 3], 'sliding', @max);
figure
subplot(1, 2, 1)
imshow(g_max, [ ])
title('(a)3x3最大值滤波器滤波结果')
n_salt = imnoise2('salt & pepper', M, N, 0, 0.1);
c = find(n_salt == 1);
f_salt = f;
f_salt(c) = 255;
g_min = colfilt(f_salt, [3, 3], 'sliding', @min);
subplot(1, 2, 2)
imshow(g_min, [ ])
title('(a)3x3最小值滤波器滤波结果')
中点滤波器
中点滤波器由下式定义:
f ^ ( x , y ) = 1 2 [ m a x ( s , t ) ∈ S x y { g ( s , t ) } + m i n ( s , t ) ∈ S x y { g ( s , t ) } ] (10) \hat f(x,y) = \frac{1}{2} \left[ \underset{(s,t) \in S_{xy}}{max} \{g(s,t)\} + \underset{(s,t) \in S_{xy}}{min} \{g(s,t)\} \right] \tag{10} f^(x,y)=21[(s,t)∈Sxymax{g(s,t)}+(s,t)∈Sxymin{g(s,t)}](10)
中点滤波器计算 f ^ ( x , y ) \hat f(x,y) f^(x,y)的 m × n m \times n m×n邻域中的最大值和最小值的中点,适用于处理随机分布的噪声如高斯噪声或均匀噪声
修正的阿尔法均值滤波器
去掉邻域 S x y S_{xy} Sxy内灰度最低的 d / 2 d/2 d/2个像素和灰度最大的 d / 2 d/2 d/2个像素,由剩余的 m n − d mn-d mn−d个元素的平均值形成的滤波器称之为修正的阿尔法均值滤波器,定义式如下:
f ^ ( x , y ) = 1 m n − d ∑ ( s , t ) ∈ S x y g r ( s , t ) (11) \hat f(x,y) = \frac{1}{mn-d} \sum_{(s,t) \in S_{xy}} g_r(s,t) \tag{11} f^(x,y)=mn−d1(s,t)∈Sxy∑gr(s,t)(11)
其中 g r ( s , t ) g_r(s,t) gr(s,t)表示剩余的 m n − d mn-d mn−d个元素的灰度, d d d的取值范围为 [ 0 , m n − 1 ] [0, mn-1] [0,mn−1], 当 d = 0 d = 0 d=0时,(11)式退化为算数均值滤波器,当 d = m n − 1 d = mn-1 d=mn−1时,(11)式退化为中值滤波器。修正的阿尔法均值滤波器在包含多种噪声的情况下很有用,如混合有高斯噪声和椒盐噪声的情况
下图(a)显示了一幅被均值为0,方差为800的加性均匀噪声污染的图像,图(b)显示了这幅图像进一步被 P a = P b = 0.1 P_a=P_b=0.1 Pa=Pb=0.1的椒盐噪声污染的图像,图(c)(d)分别是使用5x5的算数均值滤波器和几何均值滤波器滤波的结果,显然,这两个都没有起到良好地滤波结果。图(d)是使用了5x5的中值滤波器滤波的结果,图(f)是使用了5x5,d=6的修正阿尔法均值滤波的结果,这两个滤波的结果都好的多,但修正阿尔法均值滤波时的处理后的图像更平滑一些
clear
clc
close all
f_gauss = imread('Fig0512(a)(ckt-uniform-var-800).tif');
[M, N] = size(f_gauss);
figure
subplot(1, 2, 1);
imshow(f_gauss, [ ])
title('(a)被加性均匀噪声污染的图像')
n_sp = imnoise2('salt & pepper', M, N, 0.1, 0.1);
f_sp = f_gauss;
c = find(n_sp == 0);
f_sp(c) = 0;
c = find(n_sp == 1);
f_sp(c) = 255;
subplot(1, 2, 2);
imshow(f_sp, [ ])
title('(b)再次被Pa=Pb=0.1的加性椒盐噪声污染的图像')
g_mean = colfilt(f_sp, [5, 5], 'sliding', @mean);
figure
subplot(1, 2, 1)
imshow(g_mean, [ ]);
title('(c)使用5x5的算数均值滤波')
g_geomean = colfilt(im2double(f_sp) + eps, [5, 5], 'sliding', @geomean);
% g_geomean = spfilt(f_sp, 'gmean', 5, 5);
subplot(1, 2, 2)
imshow(g_geomean, [ ]);
title('(d)使用5x5的几何均值滤波')
g_median = colfilt(f_sp, [5, 5], 'sliding', @median);
figure
subplot(1, 2, 1)
imshow(g_median, [ ]);
title('(e)使用5x5的中值滤波')
% g_alpha_mean = trimed_alpha_mean(f_sp, 5, 5, 6);
% subplot(1, 2, 2)
% imshow(g_median, [ ]);
% title('(f)使用5x5,d=5的修正阿尔法均值滤波')
g_alpha_mena = spfilt(f_sp, 'atrimmed', 5, 5, 6);
subplot(1, 2, 2)
imshow(g_alpha_mena, [ ]);
title('(f)使用5x5,d=6的修正阿尔法均值滤波')
% function g = trimed_alpha_mean(f, m, n, d)
% [M, N] = size(f);
% f = padarray(f, [m, n], 0, 'both');
% g = ones(M, N);
% for i = m+1:M+m
% for j = n+1:N+n
% left = i - fix(m / 2);
% up = j - fix(n / 2);
% f_adjacent = f(left: left+m-1, up : up+n-1);
% sorted = sort(f_adjacent(:));
% left = fix(d / 2);
% g(i-m, j-n) = mean(sorted(left : m*n-left+1));
% end
% end
% g = g / (m * n -d);
% end
最后,数字图像处理Matlab版中也给出了一个spfilt函数,用来计算上面所讨论的几种均值滤波器,在此也将其代码贴出来,不过基本的原理和上面是一样的,也就不再赘述。
function f = spfilt(g, type, m, n, parameter)
%SPFILT Performs linear and nonlinear spatial filtering.
% F = SPFILT(G, TYPE, M, N, PARAMETER) performs spatial filtering
% of image G using a TYPE filter of size M-by-N. Valid calls to
% SPFILT are as follows:
%
% F = SPFILT(G, 'amean', M, N) Arithmetic mean filtering.
% F = SPFILT(G, 'gmean', M, N) Geometric mean filtering.
% F = SPFILT(G, 'hmean', M, N) Harmonic mean filtering.
% F = SPFILT(G, 'chmean', M, N, Q) Contraharmonic mean
% filtering of order Q. The
% default is Q = 1.5.
% F = SPFILT(G, 'median', M, N) Median filtering.
% F = SPFILT(G, 'max', M, N) Max filtering.
% F = SPFILT(G, 'min', M, N) Min filtering.
% F = SPFILT(G, 'midpoint', M, N) Midpoint filtering.
% F = SPFILT(G, 'atrimmed', M, N, D) Alpha-trimmed mean filtering.
% Parameter D must be a
% nonnegative even integer;
% its default value is D = 2.
%
% The default values when only G and TYPE are input are M = N = 3,
% Q = 1.5, and D = 2.
%
% Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins
% Digital Image Processing Using MATLAB, Prentice-Hall, 2004
% $Revision: 1.6 $ $Date: 2003/10/27 20:07:00 $
% Process inputs.
if nargin == 2
m = 3; n = 3; Q = 1.5; d = 2;
elseif nargin == 5
Q = parameter; d = parameter;
elseif nargin == 4
Q = 1.5; d = 2;
else
error('Wrong number of inputs.');
end
% Do the filtering.
switch type
case 'amean'
w = fspecial('average', [m n]);
f = imfilter(g, w, 'replicate');
case 'gmean'
f = gmean(g, m, n);
case 'hmean'
f = harmean(g, m, n);
case 'chmean'
f = charmean(g, m, n, Q);
case 'median'
f = medfilt2(g, [m n], 'symmetric');
case 'max'
f = ordfilt2(g, m*n, ones(m, n), 'symmetric');
case 'min'
f = ordfilt2(g, 1, ones(m, n), 'symmetric');
case 'midpoint'
f1 = ordfilt2(g, 1, ones(m, n), 'symmetric');
f2 = ordfilt2(g, m*n, ones(m, n), 'symmetric');
f = imlincomb(0.5, f1, 0.5, f2);
case 'atrimmed'
if (d <= 0) | (d/2 ~= round(d/2))
error('d must be a positive, even integer.')
end
f = alphatrim(g, m, n, d);
otherwise
error('Unknown filter type.')
end
%-------------------------------------------------------------------%
function f = gmean(g, m, n)
% Implements a geometric mean filter.
inclass = class(g);
g = im2double(g);
% Disable log(0) warning.
warning off;
f = exp(imfilter(log(g), ones(m, n), 'replicate')).^(1 / m / n);
warning on;
f = changeclass(inclass, f);
%-------------------------------------------------------------------%
function f = harmean(g, m, n)
% Implements a harmonic mean filter.
inclass = class(g);
g = im2double(g);
f = m * n ./ imfilter(1./(g + eps),ones(m, n), 'replicate');
f = changeclass(inclass, f);
%-------------------------------------------------------------------%
function f = charmean(g, m, n, q)
% Implements a contraharmonic mean filter.
inclass = class(g);
g = im2double(g);
f = imfilter(g.^(q+1), ones(m, n), 'replicate');
f = f ./ (imfilter(g.^q, ones(m, n), 'replicate') + eps);
f = changeclass(inclass, f);
%-------------------------------------------------------------------%
function f = alphatrim(g, m, n, d)
% Implements an alpha-trimmed mean filter.
inclass = class(g);
g = im2double(g);
f = imfilter(g, ones(m, n), 'symmetric');
for k = 1:d/2
f = imsubtract(f, ordfilt2(g, k, ones(m, n), 'symmetric'));
end
for k = (m*n - (d/2) + 1):m*n
f = imsubtract(f, ordfilt2(g, k, ones(m, n), 'symmetric'));
end
f = f / (m*n - d);
f = changeclass(inclass, f);
自适应滤波器是以图像中的某一点对其他点的特征变化为基础的,因此自适应滤波器的性能要优于前面所讨论的所有滤波器,代价是计算复杂度提高了。
自适应局部降噪滤波器
自适应局部降噪滤波器在任意一点 ( x , y ) (x, y) (x,y)上的响应基于以下4个量:(a) g ( x , y ) g(x, y) g(x,y), 带噪图像在点 ( x , y ) (x,y) (x,y)处的值;(b) σ η 2 \sigma_{\eta}^2 ση2,噪声的方差;(c) m L m_L mL, S x y S_{xy} Sxy中像素的局部均值。(d) σ L 2 \sigma_{L}^2 σL2, S x y S_{xy} Sxy中像素的局部方差。我们所希望的滤波器响应如下:
基于以上讨论,自适应局部降噪滤波器表达式如下:
f ^ ( x , y ) = g ( x , y ) − σ η 2 σ L 2 [ g ( x , y ) − m L ] (12) \hat f(x,y) =g(x, y) - \frac{\sigma_{\eta}^2}{\sigma_{L}^2} \left[ g(x, y) - m_L \right] \tag{12} f^(x,y)=g(x,y)−σL2ση2[g(x,y)−mL](12)
由以上讨论易得自适应局部降噪滤波器的代码如下:
function g = adaptiv_local_noise_reduction_filter(f, m, n, sig_eta)
[M, N] = size(f);
inclass = class(f);
% 将图像归一化到[0, 1]
f_pad = padarray(im2double(f), [m, n], 'replicate', 'both');
% 归一化方差
sig_eta = sig_eta / (255^2);
g = zeros(M, N);
% 填充原始图像
for i = m+1:M+m
for j = n+1:N+n
left_bound = fix(m / 2);
up_bound = fix(n / 2);
% 获得以f_pad(i, j)为中心的m*n邻域
s_xy = f_pad(i-left_bound:i-left_bound+m-1, j-up_bound:j-up_bound+n-1);
% 局部均值
ml = mean(s_xy(:));
% 局部方差
sig_L = var(s_xy(:));
if sig_eta / sig_L >= 1
g(i-m, j-n) = ml;
else
g(i-m, j-n) = f_pad(i, j) - sig_eta / sig_L * (f_pad(i, j) - ml);
end
end
end
g = changeclass(inclass, g);
end
通常情况下,噪声的方差 σ η 2 \sigma_{\eta}^2 ση2是不可知的,但我们可以通过一个恒定灰度的区域对噪声的方差进行估计。
如下图(a)显示了一幅均值为零,方差为1000的加性高斯噪声污染的图像,图(b)、(c)是分别对其进行7x7算数均值滤波和几何均值滤波的结果,可以看到,噪声被平滑,但图像也变得非常模糊。图(d)是使用自适应降噪的结果,其降噪效果与(b)(c)相当,但图像更清晰一点(注意图像左下方的8根引脚)
clear
clc
close all
f_gauss = imread('Fig0513(a)(ckt_gaussian_var_1000_mean_0).tif');
[M, N] = size(f_gauss);
figure
subplot(1, 2, 1);
imshow(f_gauss, [ ])
title('(a)被方差为1000的加性高斯噪声污染的图像')
g_mean = spfilt(f_gauss, 'amean', 7, 7);
subplot(1, 2, 2)
imshow(g_mean, [ ]);
title('(b)使用7x7的算数均值滤波')
g_geomean = spfilt(f_gauss, 'gmean', 7, 7);
figure
subplot(1, 2, 1)
imshow(g_geomean, [ ]);
title('(c)使用7x7的几何均值滤波')
g_aptive = adaptiv_local_noise_reduction_filter(f_gauss, 7, 7, 1000);
subplot(1, 2, 2)
imshow(g_aptive, [ ]);
title('(d)使用7x7的自适应局部降噪滤波')
function g = adaptiv_local_noise_reduction_filter(f, m, n, sig_eta)
[M, N] = size(f);
inclass = class(f);
% 将图像归一化到[0, 1]
f_pad = padarray(im2double(f), [m, n], 'replicate', 'both');
% 归一化方差
sig_eta = sig_eta / (255^2);
g = zeros(M, N);
% 填充原始图像
for i = m+1:M+m
for j = n+1:N+n
left_bound = fix(m / 2);
up_bound = fix(n / 2);
% 获得以f_pad(i, j)为中心的m*n邻域
s_xy = f_pad(i-left_bound:i-left_bound+m-1, j-up_bound:j-up_bound+n-1);
% 局部均值
ml = mean(s_xy(:));
% 局部方差
sig_L = var(s_xy(:));
if sig_eta / sig_L >= 1
g(i-m, j-n) = ml;
else
g(i-m, j-n) = f_pad(i, j) - sig_eta / sig_L * (f_pad(i, j) - ml);
end
end
end
g = changeclass(inclass, g);
end
function f = adpmedian(g, Smax)
%ADPMEDIAN Perform adaptive median filtering.
% F = ADPMEDIAN(G, SMAX) performs adaptive median filtering of
% image G. The median filter starts at size 3-by-3 and iterates up
% to size SMAX-by-SMAX. SMAX must be an odd integer greater than 1.
%
% Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins
% Digital Image Processing Using MATLAB, Prentice-Hall, 2004
% $Revision: 1.5 $ $Date: 2003/11/21 14:19:05 $
% SMAX must be an odd, positive integer greater than 1.
if (Smax <= 1) | (Smax/2 == round(Smax/2)) | (Smax ~= round(Smax))
error('SMAX must be an odd integer > 1.')
end
[M, N] = size(g);
% Initial setup.
f = g;
f(:) = 0;
alreadyProcessed = false(size(g));
% Begin filtering.
for k = 3:2:Smax
zmin = ordfilt2(g, 1, ones(k, k), 'symmetric');
zmax = ordfilt2(g, k * k, ones(k, k), 'symmetric');
zmed = medfilt2(g, [k k], 'symmetric');
processUsingLevelB = (zmed > zmin) & (zmax > zmed) & ...
~alreadyProcessed;
zB = (g > zmin) & (zmax > g);
outputZxy = processUsingLevelB & zB;
outputZmed = processUsingLevelB & ~zB;
f(outputZxy) = g(outputZxy);
f(outputZmed) = zmed(outputZmed);
alreadyProcessed = alreadyProcessed | processUsingLevelB;
if all(alreadyProcessed(:))
break;
end
end
% Output zmed for any remaining unprocessed pixels. Note that this
% zmed was computed using a window of size Smax-by-Smax, which is
% the final value of k in the loop.
f(~alreadyProcessed) = zmed(~alreadyProcessed);
理解这个代码的关键在于理解标志矩阵alreadyProcessed和标志位processUsingLevelB,只要理解了alreadyProcessed 是用来表示是否需要扩大邻域 S x y S_{xy} Sxy的,processUsingLevelB是用来表示是否需要进行步骤B的,这段代码就非常好理解了。
以下图(a)显示了一幅被 P a = P b = 0.25 P_a=P_b=0.25 Pa=Pb=0.25的椒盐噪声污染的图像,此时噪声水平非常高,以至于细节几乎不可见。图(b)是使用7x7的中值滤波器滤波的结果,此时虽然噪声被平滑,但图像细节也出现了损失,如图片顶部连接片的断裂。
图(c)是使用自适应中值滤波的结果,可以看到,除了平滑噪声外,该滤波器对图像的细节保留也非常好。
f_gauss = imread('Fig0514(a)(ckt_saltpep_prob_pt25).tif');
[M, N] = size(f_gauss);
figure
imshow(f_gauss, [ ])
title('(a)被Pa=Pb=0.25的椒盐噪声污染的图像')
g_median = spfilt(f_gauss, 'median', 7, 7);
figure
subplot(1, 2, 1)
imshow(g_median, [ ]);
title('(b)使用7x7的中值滤波器滤波结果')
g_adaptive_median = adpmedian(f_gauss, 7);
subplot(1, 2, 2)
imshow(g_adaptive_median, [ ]);
title('(c)使用7x7的自适应中值滤波器滤波结果')