分享

Matlab图像处理(四)——常用滤波的实现

 小白学视觉 2021-01-28

前面一讲我们已经讲解了滤波的原理和公式,为了让小伙伴更加熟悉基本原理,本将中我们采用了自编写滤波函数和Matlab自带的函数两种方式来实现中值滤波、均值滤波和高斯滤波。小伙伴可以通过点击文末“阅读原文”直接获取本文所用程序。

准备工作

在进行滤波之前需要进行一些准备操作,也就是需要找含有噪声的图片。对了突出效果、方便比较,小白用程序生成了椒盐和高斯两种噪声。

1clear all
2A=imread('origin.jpg');
3A=rgb2gray(A);
4B=imread('xiaobai.jpg');
5A_gaussian = imnoise(A,'gaussian',0,39*39/(255*255));%加入噪声函数,通过后面关键字来选取加入噪声的类型,后面两个数是高斯噪声的均值和σ
6A_salt_pepper=imnoise(A,'salt & pepper',0.05); %加入噪声函数,加入椒盐噪声,后面的参数是椒盐噪声的密度

上面代码已经给出了注释,部分函数由于在前几讲中已经出现,所以没有再次叙述。生成的两张含有噪声的图片如下:

高斯噪声

椒盐噪声

自编均值滤波实现

在自己写函数实现均值滤波的时,主要分为4个步骤:生成滤波模板、延拓被滤波图像、像素位置遍历滤波、裁剪滤波后图像。通过程序来进一步了解该过程。

1 n=5;  %滤波模板大小
2 [height, width]=size(A_salt_pepper);   %输入图像是p×q的,且p>n,q>n  
3 A_salt_pepper2=zeros(height+n-1,width+n-1); %存放延拓后的图片
4 for i=1+(n-1)/2:1+(n-1)/2+height-1
5     for j=1+(n-1)/2:1+(n-1)/2+width-1
6         A_salt_pepper2(i,j)=A_salt_pepper(i-(n-1)/2,j-(n-1)/2);
7     end
8 end
9 A_salt_pepper3=A_salt_pepper2;   %灰度值更改后会对后续的滤波产生影响,因此需要一个不变的图片
10a(1:n,1:n)=1;
11for i=1:height  
12    for j=1:width  
13        c=A_salt_pepper3(i:i+(n-1),j:j+(n-1)).*a; %取出x1中从(i,j)开始的n行n列元素与模板相乘  
14        s=sum(sum(c));                 %求c矩阵中各元素之和  
15        A_salt_pepper2(i+(n-1)/2,j+(n-1)/2)=s/(n*n); %将与模板运算后的各元素的均值赋给模板中心位置的元素  
16    end  
17end  
18A_salt_pepper2=uint8(A_salt_pepper2((n-1)/2+1:height+(n-1)/2,(n-1)/2+1:width+(n-1)/2));%通过计算,此处只是一个矩阵,用uint8将矩阵变成图像
19imshow(A_salt_pepper2);
20title('自己编写均值滤波图')

代码中同样有比较详细的注释,这里就不在重复。程序是对椒盐噪声进行的滤波,接下来看一下运行的结果:

虽然去掉了椒盐噪声,但是还是可以发现图像不是很清晰。

高斯滤波的程序和该方法一样,只是将程序中的滤波模板换成上一期讲解中的滤波模板即可,这里不在做过多讲解。

自编中值滤波实现

中值滤波的实现步骤与均值滤波的方式相同,只不过不需要生成滤波模板,所以大致可以分为3个步骤:延拓被滤波图像、像素位置遍历滤波、裁剪滤波后图像。通过程序来进一步了解该过程。

1  for i=1:height  
2      for j=1:width
3          c=A_salt_pepper3(i:i+(n-1),j:j+(n-1)); %取出x1中从(i,j)开始的n行n列元素,即模板(n×n的)  
4          e=c(1,:);      %是c矩阵的第一行  
5          for u=2:n  
6              e=[e,c(u,:)];     %将c矩阵变为一个行矩阵      
7          end  
8          mm=median(e);      %mm是中值  
9          A_salt_pepper2(i+(n-1)/2,j+(n-1)/2)=mm;   %将模板各元素的中值赋给模板中心位置的元素  
10     end  
11 end  
12 A_salt_pepper2=uint8(A_salt_pepper2((n-1)/2+1:height+(n-1)/2,(n-1)/2+1:width+(n-1)/2));
13 imshow(A_salt_pepper2);
14 title('自己编写中值滤波图')

注释已经在程序中给出,这里不在做过多的讲解。这里只给出了像素位置遍历滤波部分和裁剪部分程序,可用均值滤波的延拓图像程序。我们用椒盐噪声来验证一下滤波效果:

自带函数滤波

前面我们通过自己别写程序实现了图像滤波,但是作为一个强大的“付费”软件,公司当然会让我们钱画的比较值啦。其实Matlab内部已经集成好了很多滤波的函数,并不需要我们自己一点点的编写。使用内置的函数会让程序变得更加简单,下面小白就带大家一起用内置函数来实现三种滤波

当然,第一步还是需要生成滤波模板,不过这里就简单很多了,可以用下面的函数实现:

1%% 生成滤波模板
2 A_g_mat=fspecial('gaussian',[5 5],3); %生成高斯序列
3% A_g_mat=[0.003 0.013 0.022 0.013 0.003;
4%      0.013 0.059 0.097 0.059 0.013;
5%      0.022 0.097 0.159 0.097 0.022;
6%      0.013 0.059 0.097 0.059 0.013;
7%      0.003 0.013 0.022 0.013 0.003];
8A_avr_mat=fspecial('average',3);%生成均值滤波序列
9% A_avr_mat=[0.1111 0.1111 0.1111 0.1111;
10%            0.1111 0.1111 0.1111 0.1111;
11%            0.1111 0.1111 0.1111 0.1111;
12%            0.1111 0.1111 0.1111 0.1111;]

在这里面,小白调用了函数,也自己写了一个高斯滤波模板,主要目的是为了验证我们前一讲的高斯模板的正确性,以及说明调用内置函数和自己手写函数并没有区别。

现在有了滤波模板后,首先是对高斯噪声进行高斯滤波、均值滤波、中值滤波。具体程序如下:

1 %% 处理高斯噪声
2
A_g_image_g=imfilter(A_gaussian,A_g_mat); %用生成的高斯序列进行滤波
3A_g_image_m=medfilt2(A_gaussian,[9 9]); % 中值滤波,后面的参数为滤波模板的尺寸
4A_g_image_a=imfilter(A_gaussian,A_avr_mat);
5figure(1)
6imshow(A_gaussian);title('含有高斯噪声的图像')
7figure(2)
8imshow(A_g_image_g);title('高斯滤波处理高斯噪声后的图像')
9figure(3)
10imshow(A_g_image_m);title('中值滤波处理高斯噪声后的图像')
11figure(4)
12imshow(A_g_image_a);title('均值滤波处理高斯噪声后的图像')
13figure(5)
14subplot(2,2,1)
15imshow(A_gaussian);title('含有高斯噪声的图像')
16subplot(2,2,2)
17imshow(A_g_image_g);title('高斯滤波处理高斯噪声后的图像')
18subplot(2,2,3)
19imshow(A_g_image_m);title('中值滤波处理高斯噪声后的图像')
20subplot(2,2,4)
21imshow(A_g_image_a);title('均值滤波处理高斯噪声后的图像')

上面的程序看着比较长,实际上在创建好滤波模板后,3句命令就将三种滤波完成。有时我们在实际工程中,滤波只是对信号处理的一部分,那通过调用内部函数是很方便的。上面程序是对高斯噪声进行三种滤波,为了让小伙伴清晰的看出来滤波效果,小白将滤波后的图片单独展示出来以及放在一起展示出来。

高斯滤波可以通过调整滤波模板的大小和σ值改变滤波效果,在实际项目中需要根据具体情况进行选择。小伙伴可以下载本文的程序自行调试,查看不同高斯模板的滤波效果

对了更加清晰的说明情况,接下来用中值滤波来处理一下椒盐噪声。由于滤波模板程序已经给出,这里直接给出滤波程序。

1%% 处理椒盐噪声
2
A_s_image_g=imfilter(A_salt_pepper,A_g_mat); %用生成的高斯序列进行滤波
3A_s_image_m=medfilt2(A_salt_pepper,[3 3]);
4A_s_image_a=imfilter(A_salt_pepper,A_avr_mat);
5figure(6)
6imshow(A_salt_pepper);title('含有椒盐噪声的图像')
7figure(7)
8imshow(A_s_image_g);title('高斯滤波处理椒盐噪声后的图像')
9figure(8)
10imshow(A_s_image_m);title('中值滤波处理椒盐噪声后的图像')
11figure(9)
12imshow(A_s_image_a);title('均值滤波处理椒盐噪声后的图像')
13figure(10)
14subplot(2,2,1)
15imshow(A_salt_pepper);title('含有椒盐噪声的图像')
16subplot(2,2,2)
17imshow(A_s_image_g);title('高斯滤波处理椒盐噪声后的图像')
18subplot(2,2,3)
19imshow(A_s_image_m);title('中值滤波处理椒盐噪声后的图像')
20subplot(2,2,4)
21imshow(A_s_image_a);title('均值滤波处理椒盐噪声后的图像')

程序和高斯滤波没有差别,重点查看一下滤波的效果。

通过对比运行结果我们可以看出,中值滤波几乎是很好的去除掉了椒盐噪声,边缘极个别没有被去掉的噪声点也是因为图像延拓采用的是用0填充的方式,如果是复制的方式将会去除掉这种效果。

结论

无论采用哪种滤波方式,都无法完全的去除掉图像中的噪声,只能最大程度上的减小这种噪声对图像的影响。

三种噪声各有自己的长出,而且每种滤波方式都可以通过修改滤波模板来调整滤波的效果,在实际的应用中需要根据情况灵活的选择,并加以运用。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多