空间域滤波

空间域滤波基础

  某些邻域处理工作是操作邻域的图像像素值以及相应的与邻域有相同维数的子图像的值。 这些子图像可以被称为滤波器、掩模、核、模板或窗口,其中前三个词是更为普遍的术语。 在滤波器子图像中的值是系数值,而不是像素值。 空间滤波就是在待处理图像中逐点地移动掩模。在每一点 (x, y) 处,滤波器在该点的响应通过事先定义的关系来计算。 对于线性空间滤波,其响应由滤波器系数与滤波掩模扫过区域的相应像素值的乘积之和给出。

 

 

  对于一个尺寸为 m×n 的掩模,我们假设 m=2a+1 且 n=2b+1,这里的 a、b 为非负整数。在后续的讨论中,处理的掩模的长与宽都为奇数。一般来说,在 M×N 的图像 f 上,用 m×n 大小的滤波器掩模进行线性滤波由下式给出:

  这里,a=(m-1)/2 且 b=(n-1)/2。 为了得到一幅完整的经过滤波处理的图像,必须对 x=0, 1, 2, …, M-1 和 y=0, 1, 2, …, N-1 依次应用公式。这样,就保证了对图像中的所有像素进行了处理。 式中的线性滤波处理与频率域中卷积处理的概念很相似。因此,线性空间滤波处理经常被称为“掩模与图像的卷积”。类似地,滤波掩模有时也可以称为“卷积模板”或“卷积核”。

当滤波中心靠近图像轮廓时发生的情况

  考虑一个简单的大小为 n×n 的方形掩模,当掩模中心距离图像边缘为 (n-1)/2 个像素时,该掩模至少有一条边与图像轮廓相重合。如果掩模的中心继续向图像边缘靠近,那么掩模的行或列就会处于图像平面之外。

方法一:最简单的方法就是将掩模中心点的移动范围限制在距离图像边缘不小于 (n-1)/2 个像素处。 如果要保持与原图像一样大小,可以直接将未处理的图像边缘像素直接复制到结果图像,或者用全部包含于图像中的掩模部分滤波所有像素。通过这种方法,图像靠近边缘部分的像素带将用部分滤波掩模来处理。

方法二:在图像边缘以外再补上 (n-1)/2 行和 (n-1)/2 列灰度值为0(也可为其它常值)的像素点,或者将边缘复制补在图像之外。

平滑空间滤波器

  上图显示了两个 3×3 的平滑滤波器。 第一个滤波器产生掩模下标准的像素平均值,这从把掩模系数代入前面的线性滤波公式可清楚地看出:

  第二种掩模也叫做加权平均,使用这一术语是指用不同的系数乘以像素,这样,从权值上看,一些像素比另一些更为重要。对于第二种掩模,处于掩模中心位置的像素比其它任何像素的权值都要大。因此,在均值计算中给定的这一像素显得更为重要,而距离掩模中心较远的其它像素就显得不太重要。

代码实现:

wextend 为扩展函数:

详细参数解释:http://www.ece.northwestern.edu/local-apps/matlabhelp/toolbox/wavelet/wextend.html

img=imread('A.png');
img=rgb2gray(img);

[M,N]=size(img);
img_result=zeros(M,N);  %预生成,提高速度

model_size=3;  %模板尺寸
expand_size=floor(model_size/2);
model=1/(model_size*model_size).*ones(model_size,model_size);  % 3*3卷积核

expand_img=double(wextend('2D','zpd',img,expand_size));%扩展0,也就是增加padding

for i=1:M
    for j=1:N
        ave=sum(sum(expand_img(i:i+model_size-1,j:j+model_size-1).*model));
        img_result(i,j)=ave;
    end
end

img_result=uint8(img_result);
subplot(1 ,2, 1);
title('原图像')
imshow(img)
subplot(1 ,2, 2);
imshow(img_result)
da = ['模板大小为' num2str(model_size) ',变化后的图像'];
title(da)

结果图像:

模板为15

中值滤波

中值滤波和均值滤波不同的地方是,中值滤波是对图像的像素值进行排序,取中间的像素值赋给新的图像。
主要功能:使拥有不同灰度的点看起来更接近于它的邻近值。
主要用途:去除“椒盐”噪声

img = imread('B.png');
img=rgb2gray(img);

[M , N] = size(img);%图片尺寸
img_result = zeros(M, N);%预生成,提高速度

muban_size = 3;%模板尺寸
expand_size = floor(muban_size / 2);%扩展尺寸
muban = ones(muban_size, muban_size);


expand_img = double(wextend('2D','zpd', img, expand_size));%扩展0,转double为了矩阵运算

for i=1:M
    for j=1:N
        mat = expand_img(i:i+muban_size-1,j:j+muban_size-1) .* muban; %取出x1中从(i,j)开始的n行n列元素与模板相乘
        mat = mat(:);%转数组
        mat = sort(mat);%排序
        if mod(muban_size, 2)==1
            img_result(i,j) = mat(floor(muban_size*muban_size/2)+1);%取中间
        else
            img_result(i,j) = (mat(muban_size*muban_size/2) + mat(muban_size*muban_size/2+1))/2;
        end
    end
end

img_result = uint8(img_result);%转int8,图像
subplot(1 ,2, 1);
title('原图像')
imshow(img)
subplot(1 ,2, 2);
imshow(img_result)
da = ['模板大小为' num2str(muban_size) ',变化后的图像'];
title(da)

 

posted @ 2021-01-14 14:34  为红颜  阅读(825)  评论(0编辑  收藏  举报