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(二维模板)

MATLAB-中值滤波原理、实现及应用_第1张图片

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

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

MATLAB-中值滤波原理、实现及应用_第2张图片

重要特性

MATLAB-中值滤波原理、实现及应用_第3张图片

实现方法

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

MATLAB-中值滤波原理、实现及应用_第4张图片

图像处理程序

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方形窗口,使用其他窗口仅需修改一下数字)

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

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

MATLAB-中值滤波原理、实现及应用_第5张图片

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

3*3方形窗口

MATLAB-中值滤波原理、实现及应用_第6张图片

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

MATLAB-中值滤波原理、实现及应用_第7张图片

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

MATLAB-中值滤波原理、实现及应用_第8张图片

 最终效果

MATLAB-中值滤波原理、实现及应用_第9张图片

对比

MATLAB-中值滤波原理、实现及应用_第10张图片

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

5*5方形窗口

MATLAB-中值滤波原理、实现及应用_第11张图片

横线窗口(5像素点)

MATLAB-中值滤波原理、实现及应用_第12张图片

竖线窗口(5像素点)

MATLAB-中值滤波原理、实现及应用_第13张图片

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

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

MATLAB-中值滤波原理、实现及应用_第14张图片

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

MATLAB-中值滤波原理、实现及应用_第15张图片

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

应用与注意事项

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

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

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

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

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

再推一次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

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

你可能感兴趣的:(数字图像处理,matlab,图像处理,矩阵)