本文共 8362 字,大约阅读时间需要 27 分钟。
均值滤波和和中值滤波都可以起到平滑图像,虑去噪声的功能。均值滤波采用线性的方法,平均整个窗口范围内的像素值,均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。均值滤波对高斯噪声表现较好,对椒盐噪声表现较差。中值滤波采用非线性的方法,它在平滑脉冲噪声方面非常有效,同时它可以保护图像尖锐的边缘,选择适当的点来替代污染点的值,所以处理效果好,对椒盐噪声表现较好,对高斯噪声表现较差。
在对图像应用滤波器进行过滤时,边界问题是一个需要处理的问题。一般来说,有3种处理的方法。
不对图像的边界作任何处理,在对图像进行滤波时,滤波器没有作用到图像的四周,因此图像的四周没有发生改变。
对图像的边界做扩展,在扩展边界中填充0,对于边长为2k+1的方形滤波器,扩展的边界大小为k,若原来的图像为[m, n],则扩展后图像变为[m+2k, n+2k]。进行滤波之后,图像会出现一条黑色的边框。
扩展与 填充0 的扩展类似,只不过填充0的扩展是在扩展部分填充0,而这个方法是填充距离最近的像素的值。
该函数为spacelFilter,输入为需要进行滤波的图像(L = 256,像素值为0-255的灰度图像),方形滤波器(大小为2k+1,值类型为uint8),输出为经过滤波器滤波之后的图像。该函数滤波采用填充最近像素值的方法,结果图像不会出现黑边。
function [image_out] = spacelFilter(image_in, filter) % (线性)均值滤波函数 % 输入为需要进行空间滤波的灰度图像,线性方形滤波器 % 输出为经过滤波之后的图像 % 图像边缘的填充为最近的像素值,目的是消除填充 0时会出现的黑框 % 滤波器的大小为 n * n, n = 2 * k + 1, k为整数 % 输入图像大小为 m * n, 灰度图像,像素值范围为 0 -255,L = 256 [m, n] = size(image_in); [mf, nf] = size( filter); k = (mf - 1) / 2; image2 = zeros(m+ 2*k, n+ 2*k, 'double'); image_out = zeros(m, n, 'uint8'); coeff = sum( filter(:)); % 填充部分 % 内部直接复制 for i = 1+k : m+k for j = 1+k : n+k image2(i, j) = image_in(i-k, j-k); end end % 填充上下边缘 for i = 1 : k for j = 1 : n image2(i, j+k) = image_in( 1, j); image2(m+k+i, j+k) = image_in(m, j); end end % 填充左右边缘 for i = 1 : m for j = 1 : k image2(i+k, j) = image_in(i, 1); image2(i+k, n+k+j) = image_in(i, n); end end % 填充四个角 for i = 1 : k for j = 1 : k image2(i, j) = image_in( 1, 1); %填充左上角 image2(i, j+n+k) = image_in( 1, n); %填充右上角 image2(i+n+k, j) = image_in(m, 1); %填充左下角 image2(i+n+k, j+n+k) = image_in(m, n); %填充右下角 end end % 滤波部分 for i = 1+k : m+k for j = 1+k : n+k sub_image = image2(i-k:i+k, j-k:j+k); temp1 = double( filter ') .* double(sub_image); temp2 = sum(temp1(:)) / coeff; image_out(i-k, j-k) = uint8(temp2); end end end
% 滤波部分 for i = 1+k : m+k for j = 1+k : n+k sub_image = image2(i-k:i+k, j-k:j+k); temp = median(sub_image(:)); image_out(i-k, j-k) = uint8(temp); end end
为了方便,我在spacelFilter函数中增加了中值滤波部分,增加了一个返回值,这样spacelFilter函数的返回值为[image1,image2],image1为均值滤波图像,image2为中值滤波图像。
close all; clear all; clc; image = imread( '2.tif'); [ m, n] = size(image); %模板大小 k = 3; myFilter = zeros(k, k, 'uint8'); for i = 1 : k for j = 1 : k myFilter ( i, j ) = 1; end end [ image2, image3] = spacelFilter(image, myFilter); image4 = medfilt2(image, [ 3 3]); figure; subplot( 2, 2, 1), imshow(image), title( '原图像'); subplot( 2, 2, 2), imshow(image2), title( '3*3均值滤波图像'); subplot( 2, 2, 3), imshow(image3), title( '3*3中值滤波图像'); subplot( 2, 2, 4), imshow(image4), title( 'matlab自带的中值滤波图像');