提出原因
常规的中值滤波器,在噪声的密度不是很大的情况下(根据经验,噪声的出现的概率小于0.2),效果不错。但是当概率出现的概率较高时,常规的中值滤波处理后,仍然具有噪声点,并丢失了细节和边缘,效果不是很好。
目的
- *滤除椒盐噪声
- *平滑其他非脉冲噪声
- *尽可能的保护图像中细节信息,避免图像边缘的细化或者粗化。
原理
在模板窗口Sxy定义的滤波器区域内定义如下变量:
Zmin=min(Sxy),模板窗口Sxy中的最小灰度值
Zmax=max(Sxy),模板窗口Sxy中的最大灰度值
Zmed=med(Sxy),模板窗口Sxy中的灰度值的中值
Zxy,坐标(x,y)处的灰度值
Smax,Sxy允许的最大尺寸
计算步骤
进程A:
A1=Zmed-Zmin
A2=Zmed-Zmax
如果A1>0且A2<0,则转至进程B
否则增大窗口尺寸
如果窗口尺寸<=Smax,则重复进程A
否则输出Zmed
进程B:
B1=Zxy-Zmin
B2=Zxy-Zmax
如果B1>0且B2<0,则输出Zxy
否则输出Zmed
可以看到,步骤中是对每个模板依次比较的,但是在matlab中更方便直接用矩阵对整体运算。
这里有两个前提函数:
ordfilt2()%二维统计顺序滤波函数
medfilt2()%中值滤波
ordfilt2()用法
在MATLAB图像处理工具箱中提供了二维统计顺序滤波函数ordfilt2函数。二维统计顺序滤波是中值滤波的推广,对于给定的n个数值{al ,a2,...,an},将它们按大小顺序排列,将处于第k个位置的元素作为图像滤波输出,即序号为k的二维统计滤波。ordfilt2函数语法格式为:
Y=ordfilt2(X,order,domain)
Y=ordfilt2(X,order,domain,S)
其功能是:对图像X作顺序统计滤波,order为滤波器输出的顺序值,domain为滤波窗口。S是与domain大小相同的矩阵,它是对应domain中非零值位置的输出偏置,这在图形形态学中是很有用的。例如:
Y=ordfilt2(X,5,ones(3,3)),相当于3×3的中值滤波
Y=ordfilt2(X,1,ones(3,3)),相当于3×3的最小值滤波
Y=ordfilt2(X,9,ones(3,3)),相当于3×3的最大值滤波
代码实现
自适应中值滤波函数定义:
function II=adp_median(I,Smax)
%自适应中值滤波
if (Smax<=1)||(Smax/2==round(Smax/2))||(Smax~=round(Smax))%Smax约束,噪声密度越大,Smax应当设置越高
error('Smax must be an odd integer >1');
end
%初始化
II=I;
II(:)=0;
alreadyProcessed=false(size(I));
%迭代
for k=3:2:Smax
zmin=ordfilt2(I,1,ones(k,k),'symmetric');
zmax=ordfilt2(I,k*k,ones(k,k),'symmetric');
zmed=medfilt2(I,[k k],'symmetric');
processUsingLevelB=(zmed>zmin)&(zmax>zmed)&(~alreadyProcessed);%需要转到B步骤的像素
zB=(I>zmin)&(zmax>I);
outputZxy=processUsingLevelB&zB;%满足步骤A,B的输出原值 对应的像素位置
outputZmed=processUsingLevelB&~zB;%满足A,不满足B的输出中值 对应的像素位置
II(outputZxy)=I(outputZxy);
II(outputZmed)=zmed(outputZmed);
alreadyProcessed=alreadyProcessed|processUsingLevelB;%处理过的像素
if all(alreadyProcessed(:))
break;
end
end
II(~alreadyProcessed)=I(~alreadyProcessed);%超过窗口大小没被处理的像素位置 输出原值
mian主函数 调用并与中值滤波比较:
I=imread('cameraman.tif');
IF=imnoise(I,'salt & pepper',0.4);
f2=medfilt2(IF,[3,3]);%中值滤波后的图像
ff=adp_median(IF,19);
subplot(2,2,1);
imshow(I);
title('原图');
subplot(2,2,2);
imshow(IF);
title('椒盐噪声污染后的图像');
subplot(2,2,3);
imshow(f2);
title('中值滤波');
subplot(2,2,4);
imshow(ff);
title('自适应中值滤波'); ```
效果:
![这里写图片描述](https://img-blog.csdn.net/20180427184608786?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1NjA4Mjc3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)