matlab 图像 卷积滤波,利用二维卷积做图像噪声滤波

前言

不论是野外数据采集,还是图像处理,实际二维数据都会存在噪声!用卷积对二维数据降噪是十分常用的一种方法!其原理还是利用卷积可以改变原始数据矩阵中的数值大小。本文主要介绍两种最为常见的二维卷积滤波方法:"均值滤波"与"中值滤波"。

均值滤波与中值滤波原理

原理一句话:原来卷积是两个小矩阵的"点乘再相加(卷积神经网络里的操作)",现在是"点乘相加后求平均(均值滤波)"和"点乘后取中值(中值滤波)"。图1非常明显易懂:

图1:均值滤波与中值滤波原理图

了解了原理,可以很简单的用matlab实现二维卷积滤波的程序。

噪声例子

本文主要使用两种常见的、matlab自带的:"高斯随机噪声"和"椒盐黑白噪声"。直接使用一条语句就可以为原始图像加噪声:

data = imread('zxc.jpg'); % 数据——最好比卷积核的尺寸大

data = im2double(data); % 原图像进来是uint8,矩阵运算时double 故要转一下

data = rgb2grey(data); % 转为灰度图像方便

noise_data1 = imnoise(data, 'gaussian', 0.2); % 加入高斯噪声的命令

noise_data2 = imnoise(data, 'salt & pepper', 0.3); % 加入椒盐噪声的命令

对应的噪声所带来的影响如下:图2是原始灰度图像,图3是分别加了两种噪声后的效果:

图2:原始灰度图像

图3:左图是加了高斯噪声效果图,右图是加了椒盐噪声效果图

均值滤波与中值滤波效果

分别用这两种滤波方法对这两种噪声进行滤波,看看效果怎么样:图4是均值滤波对两种噪声的处理效果,图5是中值滤波对两种噪声的处理效果。

图4:均值滤波分别对高斯、椒盐噪声处理效果

图5:中值滤波分别对高斯、椒盐噪声处理效果

效果对比:

对高斯噪声,两种滤波方法都还不错,但很明显均值滤波自身的缺点把图像模糊了;

对椒盐噪声,很明显中值滤波要比均值滤波很的多!虽然中值滤波结果中还是一些"盐噪声(白点)"去不掉!但其图像恢复效果已经很不错了。(注:对椒盐噪声的去噪,只有!只有!中值滤波效果不错)。

Matlab实现

均值滤波实现如下:

clc; clear;

data = imread('zxc.jpg'); % 数据——最好比卷积核的尺寸大

data = im2double(data); % 原图像进来是uint8,矩阵运算时double 故要转一下

% rgb转为灰度图像

data = rgb2gray(data);

figure(1);

imshow(data);

title('原始灰度值图像');

% 高斯噪声: 均值为m,方差为var的高斯噪声加到图像中 var越大越模糊

% noise_data = imnoise(data, 'gaussian', 0.2);

% 椒盐噪声: 0.1是全图10%的程度受污染

noise_data = imnoise(data, 'salt & pepper', 0.3);

% noise_data = im2double(noise_data); % 这里记得要先转为double类型

figure(2);

imshow(noise_data);

title('加入"高斯噪声"后图像')

% 开始卷积均值滤波:

% x = zeros(3,3)+1; % 卷积核——必须是方阵且为奇数行/列

x = zeros(5,5)+1;

x = x/length(x(:)); % 均值专用

x = rot90(rot90(x)); % 新的卷积核

% 核的尺寸

size_x = size(x);

row_x = size_x(1); % 核的行数

col_x = size_x(2); % 核的列数

% 数据的尺寸

size_data = size(data);

row_data = size_data(1); % 数据的行数

col_data = size_data(2); % 数据的列数

% 核的中心元素:

centerx_row = round(row_x/2);

centerx_col = round(col_x/2);

centerx = x(centerx_row,centerx_col);

% 对原始数据扩边:

data_tmp = zeros(row_data+row_x-1,col_data+row_x-1);

data_tmp(centerx_row:centerx_row+row_data-1,centerx_row:centerx_row+col_data-1) = noise_data;

data_k = data_tmp;

% 扩边后新数据矩阵尺寸:

size_data_k = size(data_k);

row_data_k = size_data_k(1);

col_data_k = size_data_k(2);

% m = centerx_row:row_data+row_x-2

% 开始卷积计算: m n 是新数据矩阵的正常索引

result = zeros(row_data_k,col_data_k);

% m n一般卷积步长都是1

for m = centerx_row:centerx_row+row_data-1

for n = centerx_row:centerx_row+col_data-1

% tt是临时与卷积核大小相同的数据中的部分矩阵:

tt = data_k(m-(centerx_row-1):m+(centerx_row-1),n-(centerx_row-1):n+(centerx_row-1));

% juan是中间每一次卷积计算求和的中间量:

juan = sum(x.*tt);

result(m,n) = sum(juan(:));

end

end

% 求掉之前扩边的0:

result = result(centerx_row:centerx_row+row_data-1,centerx_row:centerx_row+col_data-1);

% 做图:

figure(3);

imshow(result)

title('二维卷积均值滤波后图像');

中值滤波实现如下:只需修改两个for循环那部分

% m n一般卷积步长都是1

for m = centerx_row:centerx_row+row_data-1

for n = centerx_row:centerx_row+col_data-1

% tt是临时与卷积核大小相同的数据中的部分矩阵:

tt = data_k(m-(centerx_row-1):m+(centerx_row-1),n-(centerx_row-1):n+(centerx_row-1));

% juan是中间每一次卷积计算求和的中间量:

juan = median(x.*tt);

result(m,n) = median(juan(:));

end

end

结尾附上自行车的原始图片,方便大家直接测试:

文中用到的图片 提取码:i20n

你可能感兴趣的:(matlab,图像,卷积滤波)