靖harry

Talk is cheap,show me the code!

中值滤波

1
阅读(1734)

中值滤波

(1)基本原理

        图像的中值滤波是一种非线性图像处理方法,是统计排序滤波器的一种典型应用。与之前介绍的均值处理的思想有所不同,中值滤波是通过对邻域内像素按灰度排序的结果决定中心像素的灰度。具体的操作过程如下:用一个奇数点的移动窗口,将窗口中心点的值用窗口内各点的中值代替。假设窗口内有5个点,其值为1,2,3,4和5,那么此窗口内各点的中值即为3,也就是用3来代替中心点的像素值。

        中值滤波对于滤除脉冲干扰及图像扫描噪声最为有效,还可以克服线性滤波器(如领域简单平滑滤波)带来的图像细节模糊。问题来了,为什么中值滤波的这种操作可以做到这些?由于中值滤波是一种非线性运算,相对随记输入信号做严格的数学分析比较复杂(压根不会),于是我想寻求一种通俗的解释,可以解释中值滤波能够有效果的原因。

        查阅资料,我发现数字图像存在冗余信息,具体分为六大冗余:空间冗余、时间冗余、视觉冗余、信息熵冗余、结构冗余、知识冗余。其中第一个空间冗余就可以很好的解释中值滤波的作用。空间冗余指的是:图像内部相邻像素之间存在较强的相关性而造成的冗余。简单来说就是,同一景物表面上采样点的颜色之间通常存在着空间相关性,相邻各点的取值往往相近或者相同,这就是空间冗余。而脉冲噪声通常是在一个邻域内有一个点或多个点的灰度值很高或很低,这就与周围像素存在较大差异,因此中值滤波能很好的去除这种噪声。

        在《数字图像处理 原理与实践MATLAB版》书中,作者利用简单直观的矩阵来演示了中值滤波的原理。如下所示:a表示一个5x5邻域的像素灰度,其中中点位置的像素为孤立的杂点,b位对a进行一次简单平滑处理,c为对b进行简单平滑处理的结果。从图中可以看出,简单平滑将杂点对图像的影响分担到了其他像素,并没有完全去除该影响。

        选择3x3的正方形作为采样窗口,下图显示了中值滤波去除杂点的效果。其中0位杂点,b为对a进行中值滤波的结果。

中值滤波不仅对孤立杂点的消除效果显著,对稍密集的杂点也有很好的去除效果。如下图所示。对比简单平滑的结果,不难看出中值滤波对消除离散型杂点的显著效果。


(2)编码实现

        下面这个m文件实现了使用3x3大小的窗口进行中值滤波的方法。其中边界信息没做任何处理,只是简单复制了原图像的边界像素灰度。

function I2=medfilt_my(I1)
% ***************************Copyright 2016[c]**************************
% ************************Declaration***********************************
% File name:        medfilt_my
% Author:           靖Harry                                        
% Date:             02-Aug-2016 16:27:18                                 
% Version Number:   1.0
% Abstract:  
%   Median filtering of the matrix I in two dimensions with 3x3 model.  
% *********************************end*********************************
I2 = I1;
[row,col]=size(I1);
%模板大小为3x3,忽略四条边界,因此从2:row-1,2:col-1.
for i=2:row-1
   for j=2:col-1 
      I2(i,j) =  med_sort(I1,i,j);
   end
end


function medvalue=med_sort(a,i,j)
%利用冒泡排序算法,将模板取出的9个数从小到大排序,并取出中值.
%标号i,j为中心像素的下表.
buff = zeros(1,9);
cnt = 1;

%取出模板覆盖的9个数,缓存在向量buff中,以便后续排序
for m1=i-1:i+1
   for n1=j-1:j+1
      buff(cnt) = a(m1,n1); 
      cnt = cnt+1;
   end
end

%冒泡排序(未优化)
for m2=1:8
   for n2=1:8
      if buff(n2)>buff(n2+1)
         temp = buff(n2);
         buff(n2) = buff(n2+1);
         buff(n2+1) = temp ;
      end
   end
end

%取出中值
medvalue = buff(5);

下面这段代码演示了上述中值滤波函数medfilt_my的滤波效果,为了做对比,又采用MATLAB自带函数medfilt2进行中值滤波。

clear 
clc
I1 = rgb2gray(imread('lena_pepper.png'));
I2 = medfilt_my(I1);
I3 = medfilt2(I1);
imshow(I1),title('原图');
figure,imshow(I2),title('我的函数');
figure,imshow(I3),title('Matlab自带函数');


        需要注意的是,中值滤波的窗口形状和尺寸对滤波效果影响很大,不同的图像内容和不同的应用要求,往往采用不同的窗口形状和尺寸。常用的中值滤波窗口有线状、方形、圆形、十字形以及圆环形等等。窗口尺寸一般先用3x3,再取5x5逐渐增大,直到滤波效果满意为止。就一般经验来讲,对于有缓变的较长轮廓线物体的图像,采用方形或圆形窗口为宜。对于包含有尖顶物体的图像,用十字形窗口,而窗口大小则以不超过图像中最小有效物体的尺寸为宜。如果图像中点、线、尖角细节较多(感觉就是邻域灰度值变化较大),则不宜采用中值滤波。