实验目的:
1. 自己编程实现均值滤波器和中值滤波器
2.对比两种滤波器对高斯噪声和椒盐噪声的去除效果
实验总结:
1. dX(i:i+(N-1)/2,j:j+(N-1)/2)=sum(sum( X(i:i+(N-1),j:j+(N-1)) ))/(N*N);
dX(i:i+(N-1)/2,j:j+(N-1)/2) ------为左值,取的是一个点
X(i:i+(N-1),j:j+(N-1))------为右值,取的是一个矩阵
2. s=temp(:);
temp为一个二维矩阵,temp(:) 表示将二维矩阵转为向量,转换时是按列转换,也就是将第二列补到第一列后面,依次类推
3.MATLAB中在同一个.m文件中定义多个函数需注意:
一个.m文件中只能有一个主函数,且主函数在开头
嵌套定义:注意变量重名问题,内层函数可以使用外层函数的变量,而外层函数不能使用内层函数的变量。也就是一个变量的工作区间为该变量所在的函数,在函数外该变量无效。
非嵌套定义:每个函数都有自己的工作范围,以function标识函数开始(也叫打开函数),end标识函数结束(也叫关闭函数),若没有end标识则会报错,与嵌套定义混淆。
嵌套定义举例:
function main
%% 外层函数读入原图
figure('name','原图','NumberTitle','off');
I=imread('cameraman.tif');
%-----------------------------------------------------
function Y=func1(X)
% 在内层函数中使用外层变量,合法
% 此处使用外层函数变量I以显示原图
imshow(I);
% 添加高斯噪声
Y=imnoise(X,'gaussian',0,0.1);
k=10;
end % /! function Y=func1(X)
%-----------------------------------------------------
%% 使用内层函数变量并调用内层函数
w=k; % 使用内层函数变量k
imshow(w);
J=func1(I); % 调用内层函数,添加高斯噪声
figure('name','添加高斯噪声','NumberTitle','off');
imshow(J);
end % /! function main
报错:
非嵌套定义举例:
function main
figure('name','原图','NumberTitle','off');
I=imread('cameraman.tif');
imshow(I);
J=func1(I); % 调用子函数,添加高斯噪声
figure('name','添加高斯噪声','NumberTitle','off');
imshow(J);
%end % /! function main
function Y=func1(X)
% 添加高斯噪声
Y=imnoise(X,'gaussian',0,0.1);
end % /! function Y=func1(X)
报错:
(嵌套定义和非嵌套定义http://blog.sina.com.cn/s/blog_a74f6fe7010162bh.html)
实验代码:
mainfilter2.m
clear
clc
%% 读入并显示原图
figure('name','原图','NumberTitle','off');
I=imread('cameraman.tif');
imshow(I);
%% 选择噪声
m=2; % m=1 选择高斯噪声
% m=2 选择椒盐噪声
if m==1 % 添加高斯噪声
figure('name','添加高斯噪声','NumberTitle','off');
J=imnoise(I,'gaussian',0,0.1);
imshow(J);
else if m==2 % 添加椒盐噪声
figure('name','添加椒盐噪声','NumberTitle','off');
J=imnoise(I,'salt & pepper',0.1);
imshow(J);
end
end
%% 选择滤波器
n=2; % n=1 选择均值滤波
% n=2 选择中值滤波
k=1; % 标识分隔窗口时的窗口号
w=1; % 同时选择两种滤波器
if w==1||n==1% MY均值滤波
figure('name','MY均值滤波','NumberTitle','off');
for j=3:2:9
J1=myfilter2('average',j,J);
subplot(2,2,k);
subimage(J1);
title([num2str(j),'x',num2str(j),'模版']);
k=k+1;
end
end
k=1;
if w==1||n==2% MY中值滤波
figure('name','MY中值滤波','NumberTitle','off');
for j=3:2:9
J2=myfilter2('medium',j,J);
subplot(2,2,k);
subimage(J2);
title([num2str(j),'x',num2str(j),'模版']);
k=k+1;
end
end
myfilter2.m
function Y=myfilter2(type,N,X) %主函数必须位于最上方
%二维线性数字滤波器.
%
%语法:
%---------------------------------------
% Y=MYFILTER2(type,N,X)
% 用type指定的FIR滤波器(N*N的模板)对数据X进行滤波,滤波后结果为Y.
%---------------------------------------
%
%描述:
% N指定FIR滤波器使用N*N的模板进行计算
% type 目前仅支持以下两种滤波器:
% 'average' 均值滤波器
% 'medium' 中值滤波器
%---------------------------------------
%
%举例:
% clear
% clc
% %% 读入并显示原图
% figure('name','原图','NumberTitle','off');
% I=imread('cameraman.tif');
% imshow(I);
% %% 添加高斯噪声
% J=imnoise(I,'gaussian',0,0.02);
% %% MY均值滤波
% figure('name','MY均值滤波','NumberTitle','off');
% J1=myfilter2('average',3,J);
% imshow(J1);
%
switch type
case 'average'
Y=average(N,X);
case 'medium'
Y=medium(N,X);
otherwise
Y=X;
end % /!switch
end % /!function Y=myfilter2(type,N,X)
%% average
% 领域平均滤波器,模版为NxN
function I=average(N,X)
[height,width]=size(X); % 检索图像大小
dX=double(X); % 保存计算后的图像(double类型)
for i=1:height-N+1
for j=1:width-N+1
dX(i:i+(N-1)/2,j:j+(N-1)/2)=sum(sum( X(i:i+(N-1),j:j+(N-1)) ))/(N*N);
end
end
I=uint8(dX);
end % /! function I=average(N,X)
%% medium
% 中值滤波器,模版为NxN
function I=medium(N,X)
[height,width]=size(X); % 检索图像大小
dX=double(X); % 保存计算后的图像(double类型)
for i=1:height-N+1
for j=1:width-N+1
temp=X(i:i+(N-1),j:j+(N-1)); % 取出图像中与模版对应的数据
s=temp(:); % 将矩阵转变为一个矢量
med=median(s); % 计算矢量的中值
dX(i:i+(N-1)/2,j:j+(N-1)/2)=med;% 将中值写入中心位置
end
end
I=uint8(dX);
end % /! function I=medium(N,X)
实验结果:
1.滤除高斯噪声
2.滤除椒盐噪声