matlab编程实现自适应均值滤波和自适应中值滤波

matlab编程实现自适应滤波器

  • 一、自适应均值滤波器
    • 1. 原理部分:
    • 2. 程序代码
    • 3. 结果对比
  • 二、自适应中值滤波
    • 1. 原理部分
    • 2.程序代码
    • 3. 结果对比

一、自适应均值滤波器

1. 原理部分:

加入噪声:
原理: 将图片灰度化,然后将图片像素归一化到[0,1]之间,然后添加均值为0,方差为0.1的高斯噪声,乘以255映射回图片原来的灰度级,用max(0,min(t1,255))操作将超出[0,255]的纠正。效果如图:
matlab编程实现自适应均值滤波和自适应中值滤波_第1张图片

随机变量最简单的统计量是均值和方差,这些适当的参数是自适应局部滤波器的基础。均值给出了计算均值的区域中灰度平均值的度量,而方差给出了这个区域的平均对比度的度量
matlab编程实现自适应均值滤波和自适应中值滤波_第2张图片
matlab编程实现自适应均值滤波和自适应中值滤波_第3张图片
matlab编程实现自适应均值滤波和自适应中值滤波_第4张图片

2. 程序代码

主函数:

clear;clc;
%% 导入原图像,并添加高斯噪声
image=imread("1.jpg");
image=rgb2gray(image);	%灰度化
[m,n,~]=size(image);	
% y=0+0.2*randn(m,n/2);	%只添加一半   
y=0+0.2*randn(m,n);		%全范围加上噪声
%先将其double化,再除以255 便于后面计算
t1=double(image)/255;
%加上噪声
% t1(:,(n/2+1):n)=t1(:,(n/2+1):n)+y;
t1(:,:)=t1(:,:)+y;
t1 = max(0,min(t1,1));  %处理到[0,1]
% t1(:,:)=t1(:,:)+y2;
%将像素范围扩大至0--255
t1=t1*255;
%转换为uint8类型  包含噪声的图片
t2=uint8(t1);
figure("color",[1,1,1])
subplot(1,2,1),imshow(image),title('原图');
subplot(1,2,2),imshow(t2),title('加入均值为0,标准差为0.2的高斯噪声后');

%% 计算噪声方差
t2_reshape=reshape(t1,1,1,length(t1(:)));
global_means=mean(t2_reshape);
global_vars=var(t2_reshape,1); 

%% 自适应均值滤波器
image_with_noise=t1;
image_expand=padarray(image_with_noise, [3 3]); %扩展周围一圈
image1=double(image);
image_init=padarray(image1, [3 3]); 
%扩展周围一圈,因为滤波器为7x7,可以有镜像扩充、对称扩充、常数扩充等等

imagemean=image_expand; %存储每个位置的局部均值
imagevar=image_expand;  %存储每个位置的局部方差

[width,height,z]=size(image_expand);
s=7;    %滤波器阶数
for i=1:width-s+1
    for j=1:height-s+1
        box=image_expand(i:i-1+s,j:j-1+s);
        boxs=reshape(box,1,1,length(box(:)));
        means=mean(boxs);   %求均值
        imagemean(i+(s-1)/2,j+(s-1)/2)=means;
        vars=var(boxs,1);   %求方差
        imagevar(i+(s-1)/2,j+(s-1)/2)=vars;
    end
end
image_expand=image_expand(3+1:width-3,3+1:height-3);
imagemean=imagemean(3+1:width-3,3+1:height-3);	%去掉扩充的边缘
imagevar=imagevar(3+1:width-3,3+1:height-3);	%去掉扩充的边缘
noise = mean2(imagevar);%估计全局噪声方差

%% 书上公式计算得到的滤波结果
image_new=image_expand-(noise./imagevar.*(image_expand-imagemean));
image_new = max(0,min(image_new,255));  %处理到[0,255]
image_new=uint8(image_new);

%% matlab源码做了改进,效果差距不是很大
image_new_default=imagemean + (max(0, imagevar - noise) ./max(imagevar, noise)) .* (image_expand - imagemean);
image_new_default=uint8(image_new_default);
%% 画图
figure("color",[1,1,1])
subplot(2,2,1);
imshow(image);
imshow(t2);
title('原图像');
output=mean_filter(image_expand,7);
subplot(2,2,2);
imshow(output);
title('均值滤波处理后结果');

subplot(2,2,3);
imshow(image_new);
title('自适应均值滤波处理后结果');

subplot(2,2,4);
imshow(image_new_default);
title('修改后的自适应均值滤波处理后结果');


% figure("color",[1,1,1])
% image_global_var=image_expand-(global_vars./imagevar.*(image_expand-imagemean));
% image_global_var = max(0,min(image_global_var,255));  %处理到[0,255]
% image_global_var=uint8(image_global_var);
% imshow(image_global_var);
% title('global var自适应均值滤波处理后结果');

子函数:

%自编写均值滤波器
function output=mean_filter(image,n)
%输入image为原始图像,n为滤波器规模n*n,输出为滤波后的图像output
[h,w]=size(image);
imaged=double(image); %转换为double类型
imagedd=imaged;  %初始化滤波结果的规模
a=ones(n,n);
for i=1:h-n+1
    for j=1:w-n+1
        pattern=imaged(i:i+n-1,j:j+n-1).*a;
        means=sum(sum(pattern));
        imagedd(i+(n-1)/2,j+(n-1)/2)=means/(n*n);
    end
end
output=uint8(imagedd);
end

3. 结果对比

matlab编程实现自适应均值滤波和自适应中值滤波_第5张图片

二、自适应中值滤波

1. 原理部分

matlab编程实现自适应均值滤波和自适应中值滤波_第6张图片
matlab编程实现自适应均值滤波和自适应中值滤波_第7张图片
matlab编程实现自适应均值滤波和自适应中值滤波_第8张图片

2.程序代码

主程序:

gray=imread('5.png');
gray=rgb2gray(gray);	%灰度化
%% 加入噪声
gray_noise=imnoise(gray,'salt & pepper',0.5);
%% 中值滤波
M1 = medfilt2(gray_noise,[3,3]);
%% 自适应中值滤波
f1 = adaptive_median_filter(gray_noise,11);
%%
figure("color",[1,1,1]);
subplot(131)
imshow(gray_noise)
title("gray with noise")
subplot(132)
imshow(M1)
title("中值滤波")
subplot(133)
imshow(f1)
title("自适应中值滤波")

子函数:

function f = adaptive_median_filter (g, Smax) 
%% 判断邻域是否合理
if (Smax <= 1) || (Smax/2 == round(Smax/2)) || (Smax ~= round(Smax)) 
    error ('SMAX must be an odd integer > 1.') 
end
%% 
f = g; 
f(:) = 0;
%% 标记是否已处理过
alreadyProcessed = false (size(g)); 
%% 开始自适应滤波 
for k = 3:2:Smax 
    zmin = ordfilt2(g, 1, ones(k, k),'symmetric');
    zmax = ordfilt2(g, k * k, ones(k, k), 'symmetric'); 
    zmed = medfilt2(g, [k k], 'symmetric'); 
%% 判断是否进入进程B    
    processUsingLevelB  = (zmed > zmin) & (zmax > zmed) & ~alreadyProcessed;
%% 若g不是脉冲,保留原值
    zB = (g > zmin) & (zmax > g); 
    outputZxy = processUsingLevelB & zB; 
%% 若是脉冲,用Zmed替换
    outputZmed = processUsingLevelB & ~zB; 
    f (outputZxy) = g(outputZxy); 
    f (outputZmed) = zmed(outputZmed);
%% 已处理记录
    alreadyProcessed = alreadyProcessed | processUsingLevelB; 
%% 是否退出
    if all (alreadyProcessed (:)) 
        break; 
    end 
end
%% 大于窗口尺寸后,Zxy替换成Zmed输出
f (~alreadyProcessed) = zmed (~alreadyProcessed);
end

3. 结果对比

噪声密度0.2:
matlab编程实现自适应均值滤波和自适应中值滤波_第9张图片
噪声密度0.5:
matlab编程实现自适应均值滤波和自适应中值滤波_第10张图片

  1. 由图可知,当脉冲噪声的空间密度过大时,中值滤波的性能就不是很好,自适应中值滤波可以处理具有更大概率的脉冲噪声。
  2. 自适应中值滤波平滑非脉冲噪声时试图保留细节,这是 中值滤波器做不到的。

你可能感兴趣的:(matlab编程实现自适应均值滤波和自适应中值滤波)