5.3 只存在噪声的复原-空间滤波

本节所用图片素材共享于原始图片,提取码 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)Sxyg(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)Sxyg(s,t)mn1(4)
    几何均值滤波器与算数均值滤波器相比,丢失的图像细节更少
    matlab中提供了计算几何均值的函数geomean(),故几何均值滤波可通过如下代码实现:

    g = colfilt(f, [m, n], 'sliding', @geomean);
    

如下图(a)是一块8比特X射线图,图(b)显示了被均值为0,方差为400的加性高斯噪声污染的结果,图(c)和图(d)显示了使用大小为3x3的算数均值滤波和几何均值滤波的结果,显然这两种滤波器都衰减了噪声,几何均值滤波与算数均值滤波相比,图像模糊程度更小(注意例如图(c)和图(d)顶部连接片)。
5.3 只存在噪声的复原-空间滤波_第1张图片5.3 只存在噪声的复原-空间滤波_第2张图片 本节所用完整代码如下

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 )的结果,显然,这两个都没有完成去噪的任务。
    5.3 只存在噪声的复原-空间滤波_第3张图片 5.3 只存在噪声的复原-空间滤波_第4张图片5.3 只存在噪声的复原-空间滤波_第5张图片本节所用的完整代码如下:

    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)的改进十分明显。 5.3 只存在噪声的复原-空间滤波_第6张图片本节所用代码如下:

    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的盐粒噪声滤波的结果。
    另外注意,最大值滤波器扩展了图像的白色边缘,使得图像整体亮度变大,而最小值滤波器扩展了图像的黑色边缘,使的图像的整体亮度变小。

5.3 只存在噪声的复原-空间滤波_第7张图片 本节所用代码如下:

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 mnd个元素的平均值形成的滤波器称之为修正的阿尔法均值滤波器,定义式如下:
    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)=mnd1(s,t)Sxygr(s,t)(11)
    其中 g r ( s , t ) g_r(s,t) gr(s,t)表示剩余的 m n − d mn-d mnd个元素的灰度, d d d的取值范围为 [ 0 , m n − 1 ] [0, mn-1] [0,mn1], 当 d = 0 d = 0 d=0时,(11)式退化为算数均值滤波器,当 d = m n − 1 d = mn-1 d=mn1时,(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的修正阿尔法均值滤波的结果,这两个滤波的结果都好的多,但修正阿尔法均值滤波时的处理后的图像更平滑一些

5.3 只存在噪声的复原-空间滤波_第8张图片5.3 只存在噪声的复原-空间滤波_第9张图片5.3 只存在噪声的复原-空间滤波_第10张图片本节所用代码如下:

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中像素的局部方差。我们所希望的滤波器响应如下:

    1. 如果 σ η 2 \sigma_{\eta}^2 ση2为零,则简单的返回 g ( x , y ) g(x, y) g(x,y),因为这是零噪声的情形
    2. 如果 σ L 2 \sigma_{L}^2 σL2 σ η 2 \sigma_{\eta}^2 ση2高度相关,则返回 g ( x , y ) g(x, y) g(x,y)的一个近似值,这是由于高的局部方差与边缘相联系,因此应该保护这些区域
    3. 如果两个方差相等,则返回 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根引脚)

5.3 只存在噪声的复原-空间滤波_第11张图片5.3 只存在噪声的复原-空间滤波_第12张图片 本节所用完整代码如下:

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

  • 自适应中值滤波器
    自适应终止滤波以中值滤波为基础。只要脉冲噪声的空间密度不大,中值滤波性能就会很好( P a P_a Pa P b P_b Pb小于0.2),而自适应终止滤波可以处理更高密度的脉冲噪声,其原理是根据某些条件动态调整 S x y S_{xy} Sxy的大小。
    自适应中值滤波过程如下:
    步骤A:
    A 1 = z m e d − z m i n A_1 = z_{med} - z_{min} A1=zmedzmin
    A 2 = z m e d − z m a x A_2 = z_{med} - z_{max} A2=zmedzmax
     如果 A 1 > 0 A_1 \gt 0 A1>0 A 2 < 0 A_2 \lt 0 A2<0,则转到步骤B
     否则增大窗口尺寸
     如果串口尺寸 ≤ S m a x \le S_{max} Smax, 则重复步骤A
     否则输出 z m e d z_{med} zmed
    步骤B:
    B 1 = z x y − z m i n B_1 = z_{xy} - z_{min} B1=zxyzmin
    B 2 = z x y − z m a x B_2 = z_{xy} - z_{max} B2=zxyzmax
     如果 B 1 > 0 B_1 \gt 0 B1>0 B 2 < 0 B_2 \lt 0 B2<0, 则输出 z x y z_{xy} zxy
     否则输出 z m e d z_{med} zmed
    要理解该算法,首先要清楚, z m a x z_{max} zmax z m i n z_{min} zmin在算法统计中被认为是类脉冲噪声成分。
    步骤A的目的在于确定 z m e d z_{med} zmed是否是一个脉冲,如果 z m i n < z m e d < z m a x z_{min} \lt z_{med} \lt z_{max} zmin<zmed<zmax,则它不是一个脉冲噪声,进而要进行步骤B,以确定 z x y z_{xy} zxy是否是一个脉冲噪声,道理同之前一样,如果 z x y z_{xy} zxy不是脉冲噪声,那么就输出 z x y z_{xy} zxy,这样就保留了图像中的中间灰度级,减少了失真;反之,则 z x y = z m i n z_{xy} = z_{min} zxy=zmin z x y = z m a x z_{xy} = z_{max} zxy=zmax,那就相当于执行一次中值滤波,输出 z m e d z_{med} zmed。如果在步骤A中, z m e d z_{med} zmed确实是一个脉冲,就尝试增大 S x y S_{xy} Sxy以找到一个非脉冲的中值,直到最大。
    数字图像处理matlab版中提供了自适应中值滤波的函数,由于自己写的代码太烂了,自己都看不下去,所以就用原生的代码演示吧:
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)是使用自适应中值滤波的结果,可以看到,除了平滑噪声外,该滤波器对图像的细节保留也非常好。

5.3 只存在噪声的复原-空间滤波_第13张图片5.3 只存在噪声的复原-空间滤波_第14张图片本节所用完整代码如下:

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的自适应中值滤波器滤波结果')

你可能感兴趣的:(数字图像处理,数字图像处理,冈萨雷斯,Matlab,图像处理,空间滤波,均值滤波,自适应滤波器)