最近,做数字图像处理实验,简单记录一下几个挺有意思的图像处理方法。本篇主要介绍领域平均法和中值滤波法去除图像噪声,求图像SNR和PSNR及其matlab实现代码。
简单来说,就是对于每一个像素点都取它周围一圈的平均值,来降低一些像素值突变的点(即噪声点)的影响。当然,一个明显的结果就是,图片会一定程度上变模糊,于是有人提出“超限领域平均法”,即如果某个像素的灰度值大于其邻域像素的平均值,且达到一定水平,则判断该像素为噪声,继而用邻域像素的均值取代这一像素值。
代码实现如下,使用方法参见主程序注释。
% 邻域均值法去燥
function Img_average_filter=Average_filter(varargin)
narginchk(1,3);
Img_in = varargin{1};
Temp = [1 1 1;1 1 1;1 1 1]; % 默认模板
Threshold = 0; % 默认阈值
if nargin == 2
Temp = varargin{2};
elseif nargin == 3
Temp = varargin{2};
Threshold = varargin{3};
end
[n, m] = size(Img_in);
Img_raw = int32(Img_in);
[L1, L2] = size(Temp);
LL=sum(sum(Temp));
Img_average_filter = int32(zeros(n-L1+1, m-L2+1)); % 舍弃边缘信息
for i = (L1+1)/2:n-(L1-1)/2
for j = (L2+1)/2:m-(L2-1)/2
Img_raw_sub = Img_raw(i-(L1-1)/2:i+(L1-1)/2, j-(L2-1)/2:j+(L2-1)/2);
SUM = sum(sum(Img_raw_sub.*int32(Temp)));
ave = SUM/LL;
if Threshold ~= 0
if abs(Img_raw(i,j)-ave) > Threshold
Img_average_filter(i-(L1-1)/2, j-(L2-1)/2) = ave;
else
Img_average_filter(i-(L1-1)/2, j-(L2-1)/2) = Img_raw(i,j);
end
else
Img_average_filter(i-(L1-1)/2, j-(L2-1)/2) = ave;
end
end
end
简单来说,就是对于每一个像素点,取其周围像素值的中值,来代替该像素点的灰度值,当然,同样也可以加上一个阈值条件。
代码实现如下,使用方法参见主程序注释。
% 中值滤波法去燥
function Img_med_filter=Med_filter(varargin)
narginchk(1,3);
Img_in = varargin{1};
L = 3; % 默认滑动窗口尺寸
Threshold = 0; % 默认阈值
if nargin == 2
L = varargin{2};
elseif nargin == 3
L = varargin{2};
Threshold = varargin{3};
end
[n, m] = size(Img_in);
Img_raw = int32(Img_in);
Img_med_filter = int32(zeros(n-L+1, m-L+1)); % 弃边缘信息
for i = (L+1)/2:n-(L-1)/2
for j = (L+1)/2:m-(L-1)/2
Img_raw_sub = reshape(Img_raw(i-(L-1)/2:i+(L-1)/2, j-(L-1)/2:j+(L-1)/2), 1, L*L);
Img_raw_sub = sort(Img_raw_sub);
ave = Img_raw_sub((L*L+1)/2);
if Threshold ~= 0
if abs(Img_raw(i,j)-ave) > Threshold
Img_med_filter(i-(L-1)/2, j-(L-1)/2) = ave;
else
Img_med_filter(i-(L-1)/2,j-(L-1)/2) = Img_raw(i,j);
end
else
Img_med_filter(i-(L-1)/2, j-(L-1)/2) = ave;
end
end
end
function SNR(Img_raw, Img_noise, Img_filter)
Img_raw_signal = double(0);
Img_noise_signal = double(0);
Img_filter_signal = double(0);
[n0, m0] = size(Img_raw);
[n1, m1] = size(Img_filter);
stx = (n0-n1)/2+1; edx = n0-stx+1;
sty = (m0-m1)/2+1; edy = m1-sty+1;
for i = stx:edx
for j = sty:edy
Img_raw_signal = Img_raw_signal+Img_raw(i,j)*Img_raw(i,j);
Img_noise_signal = Img_noise_signal+(Img_raw(i,j)-Img_noise(i,j))*(Img_raw(i,j)-Img_noise(i,j));
Img_filter_signal = Img_filter_signal+(Img_raw(i,j)-Img_filter(i-stx+1,j-sty+1))*(Img_raw(i,j)-Img_filter(i-stx+1,j-sty+1));
end
end
Img_raw_snr = 10.0*log10(double(Img_raw_signal/Img_noise_signal));
Img_raw_psnr = 10.0*log10(double(n1*m1*255.0*255.0/Img_noise_signal));
Improved_snr = 10.0*log10(double(Img_noise_signal/Img_filter_signal));
Img_filter_snr = 10.0*log10(double(Img_raw_signal/Img_filter_signal));
Img_filter_psnr = 10.0*log10(double(n1*m1*255.0*255.0/Img_filter_signal));
disp('Input image snr = ');
disp(Img_raw_snr);
disp('Input image psnr = ');
disp(Img_raw_psnr);
disp('Improved snr = ');
disp(Improved_snr);
disp('Output image snr = ');
disp(Img_filter_snr);
disp('Output image psnr = ');
disp(Img_filter_psnr);
% ex_main.m 主程序入口
clc,clear;
% 原始图像处理
Img_raw = imread('lena.jpg');
figure(1);
[n, m, c] = size(Img_raw);
if c ~= 1
Img_raw = rgb2gray(Img_raw);
end
subplot(2, 2, 1);
imshow(Img_raw);
title('原始灰度图像');
% 加噪声
% 加‘salt & pepper’噪声
Img_noise = imnoise(Img_raw, 'salt & pepper', 0.03);
% 加‘speckle’噪声
% Img_noise = imnoise(Img_raw, 'speckle');
% Img_noise = Img_raw;
subplot(2, 2, 2);
imshow(Img_noise);
title('原始噪声图像');
% 可选邻域均值法常用模板
% Temp=[1 1 1;1 1 1;1 1 1];
% Temp=[1 1 1;1 2 1;1 1 1];
% Temp=[1 2 1;2 4 2;1 2 1];
% Temp=[1 1 1;1 0 1;1 1 1];
Temp=[1 1 1 1 1;1 1 1 1 1;1 1 1 1 1;1 1 1 1 1;1 1 1 1 1];
% 邻域平均法去噪声
% Average_filter(图片像素矩阵,模板,阈值)
% 用法:
% Average_filter(Img_noise);
% Average_filter(Img_noise, Temp);
% Average_filter(Img_noise, Temp, 35);
% 含有阈值T,即为阈值为T的超限领域平均法
Img_average_filter=Average_filter(Img_noise, Temp, 35);
subplot(2, 2, 3);
imshow(uint8(Img_average_filter));
title('邻域平均法去噪声');
disp('Average_filter');
% 求SNR和PSNR
SNR(int32(Img_raw), int32(Img_noise), int32(Img_average_filter));
% 中值滤波法去噪声
% Med_filter(图片像素矩阵,滑动窗口尺寸,阈值)
% 用法:
% Med_filter(Img_noise);
% Med_filter(Img_noise, 3);
% Med_filter(Img_noise, 3, 35);
Img_med_filter=Med_filter(Img_noise);
subplot(2, 2, 4);
imshow(uint8(Img_med_filter));
title('中值滤波法去噪声');
disp('Med_filter');
% 求SNR和PSNR
% SNR(原始图像,噪声图像,滤波后图像)
SNR(int32(Img_raw), int32(Img_noise), int32(Img_med_filter));