MATLAB-中值滤波原理、实现及应用

写了篇实现medfilt2函数功能的文章,有兴趣的朋友可以看看:medfilt2函数的实现源代码

目录

 中值滤波

原理

中值滤波窗口

重要特性

实现方法

图像处理程序

原图与加噪图像(椒盐噪声)

3*3方形窗口

5*5方形窗口

横线窗口(5像素点)

竖线窗口(5像素点)

原图与加噪图像(高斯噪声)

 3*3方形窗口(高斯噪声)

应用与注意事项

中值滤波代码


 中值滤波

原理

中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。方法是用某种结构的二维滑动模板,将板内像素按照像素值的大小进行排序,生成单调上升(或下降)的为二维数据序列。

二维中值滤波输出为

g(x,y)=med{f(x-k,y-l),(k,l∈W)}

其中,f(x,y),g(x,y)分别为原始图像和处理后图像。W为二维模板,通常为3*3,5*5区域,也可以是不同的的形状,如线状,圆形,十字形,圆环形等。

中值滤波窗口

常见的中值滤波窗口,即为上面提及的W(二维模板)

许录平《数字图像处理》(第二版) P87

以使用3*3方形窗口进行中值滤波为例,如下图,这些数据是从加椒盐噪声的图像和处理后的图像截取的一部分像素点的灰度值(非图像边缘处),对框内9个数排序,然后将中值代替原值,便是图中的156→157

重要特性

实现方法

  1. 使用上述滤波窗口取出奇数偶数个数据进行排序,
  2. 排序后,窗口点数为奇数,将中值替代原值,若为偶数则取中间两个值的平均值
  3. 下图为我已写好的程序,对应上面的全部常用窗口并有所扩展,因为源代码比较长,所以把代码放到后面,在这里放张图简略说明

图像处理程序

clear;close all;clc;

f=imread('cameraman.tif');
fsap=imnoise(f,'salt & pepper',0.05); %加入椒盐噪声
% fsap=imnoise(f,'gaussian',0.01); %加入高斯噪声
fmed=median_filtering(fsap,6,3); %中值滤波
subplot(121),imshow(f);title('原图')
subplot(122),imshow(fsap);title('加噪图像')
figure;
subplot(121),imshow(fmed);title('中值滤波处理')
subplot(122),fimg=medfilt2(fsap,[3 3]);imshow(fimg);title('medfilt2处理') %对比medfilt2函数

根据代码,会进行线状(横线与竖线)窗口以及方形窗口的中值滤波,并与medfilt2函数对比(上面的代码为3*3方形窗口,使用其他窗口仅需修改一下数字)

首先我们对原图进行加噪处理,此处加的是椒盐噪声

原图与加噪图像(椒盐噪声)

然后我们使用3*3方形的中值滤波窗口进行处理

3*3方形窗口

眼尖的朋友会发现其实我是没有处理边缘的而medfilt2函数是有处理的,因为边缘处凑不足9个像素点,所以让边缘取最近值用以消除边缘噪声

 实际处理效果如下图(图像左下角处),四个顶角取离它最近的像素点的灰度值。我们能看出边缘同时也会变得模糊

 最终效果

对比

再看看其他窗口处理的效果如何

5*5方形窗口

横线窗口(5像素点)

竖线窗口(5像素点)

 十字形、X状那些窗口不再一一展示,接下来展示一下处理高斯噪声的情况

原图与加噪图像(高斯噪声)

 3*3方形窗口(高斯噪声)

中值滤波是一个非线性滤波。它对椒盐噪声这类随机出现的噪点有比较好的平滑效果,但对于线性的噪声(如高斯噪声)效果不佳

应用与注意事项

中值滤波法对消除椒盐噪声干扰脉冲非常有效,尤其适合于目标物形状是块状时的图像滤波。

在光学测量条纹图象的相位分析处理方法中有特殊作用,但在条纹中心分析方法中作用不大。

中值滤波在图像处理中,常用于保护边缘信息(不处理边缘的话),是经典的平滑噪声的方法。

具有丰富尖角几何结构的图像,一般采用十字形滤波窗,且窗口大小最好不要超过图像中最小目标物的尺寸,否则会丢失目标物的细小几何特征。

需要保持细线状及尖顶角目标物细节时,最好不要使用中值滤波。

再推一次medfilt2函数的文章:medfilt2函数的实现源代码

中值滤波代码

function fmed=median_filtering(f,mode,num)

%中值滤波
%f为含噪图像
%返回的fmed为中值滤波处理后的图像
%mode取不同的数值代表不同的窗口,取值范围为1-8
%mode=1,为横线,num为对应的像素点,仅支持大于1的奇数
%mode=2,为竖线,num为对应的像素点,仅支持大于1的奇数
%mode=3,为十字形-5像素点
%mode=4,为十字形-9像素点
%mode=5,为X状
%mode=6,为方形,num为方形矩阵阶数,仅支持大于1的奇数
%mode=7,为菱形
%mode=8,为圆形
%统一使边缘处取最近值

[m,n]=size(f); %读取矩阵大小
fmed=f;

%开始进行中值滤波
if mode==1||mode==2 %线状窗口
    num2=(num+1)/2;
    a=ones(1,num); %提前创建矩阵提升运算速度
    if mode==1 %横线线状窗口
        for w=1:m %从第一行到最后一行
            for l=num2:n-num2+1
                for o=1:num
                    a(o)=f(w,l+o-num2); %线状窗口取值
                end
                a=sort(a); %排序
                fmed(w,l)=a(num2);
            end
        end
    elseif mode==2 %竖线线状窗口
        for w=num2:m-num2+1
            for l=1:n %从第一列到最后一列
                for o=1:num
                    a(o)=f(w+o-num2,l); %线状窗口取值
                end
                a=sort(a); %排序
                fmed(w,l)=a(num2);
            end
        end
    end
elseif mode==3||mode==5||mode==6
    if mode==3 %十字形(5个点)    
        for w=2:m-2           
            for l=2:n-2
                a(1)=f(w-1,l); %取点
                a(2)=f(w,l-1);
                a(3)=f(w,l);
                a(4)=f(w,l+1);
                a(5)=f(w+1,l);
                a=sort(a); %对a排序
                fmed(w,l)=a(3); %赋中值
            end
        end
    elseif mode==5 %X状
        for w=2:m-2           
            for l=2:n-2
                a(1)=f(w-1,l-1); %取点
                a(2)=f(w-1,l+1);
                a(3)=f(w,l);
                a(4)=f(w+1,l-1);
                a(5)=f(w+1,l+1);
                a=sort(a); %对a排序
                fmed(w,l)=a(3); %赋中值
            end
        end
    else %num阶方形
        a=zeros(num); %创造滤波窗口
        num1=(num-1)/2;
        num2=(num+1)/2;
        for w=num2:m-num1
            for l=num2:n-num1
                for i=-1*num1:num1
                    for j=-1*num1:num1
                        a(num2+i,num2+j)=f(w+i,l+j); %取点
                    end
                end
                a2=reshape(a,num^2,1); %排成一列,方便排序
                a3=sort(a2); %排序
                fmed(w,l)=a3((num^2+1)/2); %赋中值
            end
        end
    end
elseif mode==4||mode==7||mode==8
    if mode==4 %十字形(9个点)
        for w=3:m-2           
            for l=3:n-2
                a(1)=f(w-2,l); %取点
                a(2)=f(w-1,l);
                a(3)=f(w,l-2);
                a(4)=f(w,l-1);
                a(5)=f(w,l);
                a(6)=f(w,l+1);
                a(7)=f(w,l+2);
                a(8)=f(w+1,l);
                a(9)=f(w+2,l);
                a=sort(a); %对a排序
                fmed(w,l)=a(5); %赋中值
            end
        end
    elseif mode==7 %菱形
        for w=3:m-2       
            for l=3:n-2            
                a(1)=f(w-2,l); %取点                                
                a(2)=f(w-1,l-1);
                a(3)=f(w-1,l);
                a(4)=f(w-1,l+1);                
                a(5)=f(w,l-2);
                a(6)=f(w,l-1);
                a(7)=f(w,l);
                a(8)=f(w,l+1);
                a(9)=f(w,l+2);                
                a(10)=f(w+1,l-1);
                a(11)=f(w+1,l);
                a(12)=f(w+1,l+1);                
                a(13)=f(w+2,l);                
                a=sort(a); %对a排序
                fmed(w,l)=a(7); %赋中值
            end
        end
    else %圆形
        for w=3:m-2        
            for l=3:n-2             
                a(1)=f(w-2,l-1); %取点
                a(2)=f(w-2,l);
                a(3)=f(w-2,l+1);                
                a(4)=f(w-1,l-2);
                a(5)=f(w-1,l-1);
                a(6)=f(w-1,l);
                a(7)=f(w-1,l+1);
                a(8)=f(w-1,l+2);
                a(9)=f(w,l-2);
                a(10)=f(w,l-1);
                a(11)=f(w,l);
                a(12)=f(w,l+1);
                a(13)=f(w,l+2);
                a(14)=f(w+1,l-2);
                a(15)=f(w+1,l-1);
                a(16)=f(w+1,l);
                a(17)=f(w+1,l+1);
                a(18)=f(w+1,l+2);                
                a(19)=f(w+2,l-1);
                a(20)=f(w+2,l);
                a(21)=f(w+2,l+1);                
                a=sort(a); %对a排序
                fmed(w,l)=a(11); %赋中值
            end
        end
    end
end

%处理边缘
for i=1:2 %处理第1、2行、倒数第1、第2行的第3列到倒数第三列的边缘像素点
    for j=3:n-2
        fmed(i,j)=fmed(3,j);
        fmed(m+1-i,j)=fmed(m-2,j);
    end
end

for j=1:2 %处理第1、2列、倒数第1、第2列的第3行到倒数第三行的边缘像素点
    for i=3:m-2
        fmed(i,j)=fmed(i,3);
        fmed(i,n+1-j)=fmed(i,n-2);
    end
end

%处理四个顶角
fmed(1,1)=fmed(3,3);fmed(1,2)=fmed(3,3);fmed(2,1)=fmed(3,3);fmed(2,2)=fmed(3,3);
fmed(1,n)=fmed(3,n-2);fmed(1,n-1)=fmed(3,n-2);fmed(2,n)=fmed(3,n-2);fmed(2,n-1)=fmed(3,n-2);
fmed(m,1)=fmed(m-2,3);fmed(m-1,1)=fmed(m-2,3);fmed(m,2)=fmed(m-2,3);fmed(m-1,2)=fmed(m-2,3);
fmed(m,n)=fmed(m-2,n-2);fmed(m-1,n)=fmed(m-2,n-2);fmed(m,n-1)=fmed(m-2,n-2);fmed(m-1,n-1)=fmed(m-2,n-2);
end

如果觉得有用的话,能否点个赞呢?

  • 44
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值