点击蓝字
关注我们
前面一讲我们已经讲解了滤波的原理和公式,为了让小伙伴更加熟悉基本原理,本将中我们采用了自编写滤波函数和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 %% 处理高斯噪声
2A_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%% 处理椒盐噪声
2A_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填充的方式,如果是复制的方式将会去除掉这种效果。
结论
无论采用哪种滤波方式,都无法完全的去除掉图像中的噪声,只能最大程度上的减小这种噪声对图像的影响。
三种噪声各有自己的长出,而且每种滤波方式都可以通过修改滤波模板来调整滤波的效果,在实际的应用中需要根据情况灵活的选择,并加以运用。
相关阅读:
如果您喜欢本文和本公众号,
希望您能推送给周围的好友。
一个赞就是对小白的一种支持
长按上面二维码关注本公众号
本文分享自微信公众号 - 小白学视觉(NoobCV)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/4581492/blog/4593623