均值滤波是一种线性滤波器,处理思路也很简单,就是将一个窗口区域中的像素计算平均值,然后将窗口中计算得到的均值设置为锚点上的像素值。
该算法有优点在于效率高,思路简单。同样,缺点也很明显,计算均值会将图像中的边缘信息以及特征信息“模糊”掉,会丢失很多特征。
计算均值滤波时可以采用很多优化手段,例如使用积分图的方法对图像进行预处理,处理过后的图像可以通过O(1)的时间复杂度获取窗口区域中的像素和。如果使用并行以及SSE指令集来进行加速,效果会更快。
下面代码使用简单的卷积方案来实现,既然是计算窗口区域中的像素和,即使用如下卷积核即可。图像的边界部分采用padding操作处理。另外,得到的锚点像素值要进行归一化,即除以窗口尺寸大小。
clear,clc;
pauseTime = 1;
data_path = '..\Set12';
ext = ['*.jpg', '*.png', '*.jpeg'];
filePaths = [];
for i = 1 : length(ext)
filePaths = cat(1,filePaths, dir(fullfile(data_path,ext(i))));
end
noise_leval = [10,15,20,25,30,35,40,45,50,55,60,65,70];
for ii = 1:length(noise_leval)
PSNRs = zeros(1, length(filePaths));
SSIMs = zeros(1, length(filePaths));
sigma = noise_leval(ii);
for jj = 1:length(filePaths)
% 原图像
originImage = im2double(imread(filePaths(jj).name));
% 添加高斯噪声
imageWithNoise = single(originImage + sigma/255*randn(size(originImage)));
[rows, cols] = size(originImage);
y = imageWithNoise;
% 均值滤波算法
% 指定模板尺寸
boxSize = 3;
template = zeros(boxSize);
for i = 1:rows-boxSize+1
for j = 1:cols-boxSize+1
% 取模板内像素
template = imageWithNoise(i:i+(boxSize-1),j:j+(boxSize-1));
% 用均值替代模板中心点像素值
s = sum(template(:));
y(i+(boxSize-1)/2,j+(boxSize-1)/2) = s/boxSize^2;
end
end
% 计算psnr和ssim
% se2 = (y - originImage).^2;
% MSE2 = sum(se2(:)) / (rows * cols);
PSNRs(jj) = psnr(im2uint8(originImage), im2uint8(y));
SSIMs(jj) = ssim(im2uint8(originImage), im2uint8(y));
imshow(cat(2,im2uint8(originImage),im2uint8(imageWithNoise),im2uint8(y)));
title(['sigma=',num2str(sigma),' ',filePaths(jj).name,' psnr=',num2str(PSNRs(jj),'%2.2f'),'dB',' ssim=',num2str(SSIMs(jj),'%2.4f')])
drawnow;
pause(pauseTime)
% fprintf('滤波后MSE=%f\n', MSE2);
end
disp(['sigma:',sigma,'psnr:',mean(PSNRs),'ssim:', mean(SSIMs)]);
end