子函数代码:
%symmetricnearmean.m
function [y]=symmetricnearmean(x,a,b)
y=x;
[m,n]=size(x);
N=(a-1)/2;
M=zeros( 1,2*N*(N+1) );
for i=3:m-2
for j=3:n-2
k=1;
for i1=1:N
for j1=-N:N
if j1 == 0
continue;
else
if abs( x(i,j)-x(i-i1,j-j1) ) < abs( x(i,j)-x(i+i1,j+j1) )
M(1,k)=x(i-i1,j-j1);
else
M(1,k)=x(i+i1,j+j1);
end
end
k=k+1;
end
end
%%结束时四个象限内的对称点已经全部找出:一共2N*N对,只要把十字架形状的对称点再找出就行,共有2*N个
for i1= 0
for j1=1:N
if abs( x(i,j)-x(i-i1,j-j1) ) < abs( x(i,j)-x(i+i1,j+j1) )
M(1,k)=x(i-i1,j-j1);
else
M(1,k)=x(i+i1,j+j1);
end
k=k+1;
end
end
%%结束时十字架形状的对称纵轴对称点都找出,共有2*N个,现在只要把横轴对称点找出就行,一共有2*N个
for j1= 0
for i1=1:N
if abs( x(i,j)-x(i-i1,j-j1) ) < abs( x(i,j)-x(i+i1,j+j1) )
M(1,k)=x(i-i1,j-j1);
else
M(1,k)=x(i+i1,j+j1);
end
k=k+1;
end
end
%%此时,2N*N+2*N对 对称点对应的2N*N+2*N个数据都在矩阵M中,求其均值就行
y(i,j)=mean(M);
end
end
主函数:
%%确定一个(2N+1)*(2N+1)的模板,该算法找出与核心像素灰度值接近的2N*(N+1)个像素,再求这2N*(N+1)个像素的均值代替原来中心点的灰度值
I=imread('2.jpg');
I=rgb2gray(I);
[e f]=size(I);
%J=imnoise(I,'salt & pepper',0.030);
J=imnoise(I,'gaussian',0,0.02);
%%第一种算法在保持边缘和细节较第二种算法要好很多,当然第一种算法在去噪方面不如第二种
l=symmetricnearmean(J,5,5);%灰度最小方差的均值滤波器
m=commonfilt2(J,5,5);%自己编写的均或中值滤波方法
subplot(1,2,1),imshow( uint8(l) ),title('对称近邻均值滤波');
subplot(1,2,2),imshow( uint8(m)),title('自己编写的5*5均值滤波');
%2 计算三种算法的峰值信噪比
B=8; %编码一个像素用多少二进制位
MAX=2^B-1; %图像有多少灰度级
I=double(I);
l=double(l);
m=double(m);
% psnr1 = 19.7389
MES1=sum(sum((I-l).^2))/(e*f);
PSNR1=20*log10(MAX/sqrt(MES1));
% psnr2 = 22.7301
MES2=sum(sum((I-m).^2))/(e*f);
PSNR2=20*log10(MAX/sqrt(MES2));