空域滤波——均值滤波

任务

对于空域滤波主要是提供某种卷积核,使图片中与这一模板相似的成分得到增强。

平滑滤波器

均值滤波

主要思路是,将边缘像素值保留,内部置0;因为整数运算更快,所以先将边缘*9,与之后进行处理的其他像素点的范围一致,再最终/9得到滤波后图像。

均值滤波函数

%% 空域平滑滤波邻域平均
% Function:将灰度图grayImg与模板卷积
% Date:2020/10/7
% Author:leezeeyee
function meanImg=spaceG1(grayImg)
% 边缘保留,预先x9
meanImg=uint16(grayImg);
[M,N]=size(grayImg);
meanImg(2:M-1,2:N-1)=0;
meanImg=meanImg*9;
% 卷积核(此处未使用)
convCore=ones(3);
for row=2:M-1
    for col=2:N-1
        meanImg(row,col)=sum(grayImg(row-1:row+1,col-1:col+1),'all');
    end
end
meanImg=uint8(meanImg/9);
end

matlab的添加噪声函数imnoise需要下载图像处理工具箱,可以利用文章MATLAB–数字图像处理 添加椒盐噪声的方法得到椒盐噪声图像,进行滤波效果的展示。

椒盐噪声函数

%% 添加椒盐噪声
% Function:在灰度图grayImg增加椒盐噪声
% 阈值threshold调节程度大小,范围在0~1之间,默认为0.2
% Date:2020/9/24
% Author:leezeeyee
function noiseImg=pepperNoise(grayImg,threshold)
if nargin<2
    % 未提供阈值参数,默认threshold=0.2
    threshold=0.2;
end
noiseImg=grayImg;
[width,height]=size(grayImg);
%k作为判断临界点
k=threshold;
%rand(m,n)是随机生成m行n列的矩阵,每个矩阵元素都在0-1之间
%这里k都是0.2,所以小于k的元素在矩阵中为1,反之为0
a1=rand(width,height)<k;
a2=rand(width,height)<k;
%分成黑点 白点 随机
noiseImg(a1&a2)=0;
noiseImg(a1& ~a2)=255;
end

结果展示

不同大小卷积核的作用效果

教材中提到的一点,当变换不同大小的平滑模板作为卷积核时,图像效果会有变化:具体表现在,平滑模板越大,噪声消除增强,但图像更模糊。

改进函数,可以对平滑模板的大小利用传参n进行设置。

模板大小可调节函数

%% 空域平滑滤波中值平均
% Function:将灰度图grayImg与模板卷积
% n: 卷积核大小,默认为3x3。范围>=3,且为奇数,偶数则进行2*n+1处理
% Date:2020/10/7
% Author:leezeeyee
function meanImg=spaceG1n(grayImg,n)
if nargin<2
    n=3;
end
% 输入有误处理
if mod(n,2)==0 || n==1
    n=n*2+1;
    print('n 为>=3的奇数,取n=n*2+1');
end
% 像素通乘值
scale=n^2;
% 边缘保留值
keep=(n-1)/2;
% 边缘保留,预先*n^2
meanImg=uint16(grayImg);
[M,N]=size(grayImg);
meanImg(keep+1:M-keep,keep+1:N-keep)=0;
meanImg=meanImg*scale;
% % 卷积核
% convCore=ones(3);
for row=keep+1:M-keep
    for col=keep+1:N-keep
        meanImg(row,col)=sum(grayImg(row-keep:row+keep,col-keep:col+keep),'all');
    end
end
meanImg=uint8(meanImg/scale);
end

实现效果

分别将模板大小调节为3×3/5×5/7×7/9×9,对比显示,可见效果确实与推测一致。

只是由于模板越大,保留的边缘也越大,出现了边缘像素值的噪声分布明显的情况,现提出两种解决方案:

  • 直接截去边缘像素部分
  • 对边缘像素部分减小模板进行计算

下面对方法二进行实现。

边缘处理

思路是,通过补-1(不在像素值0~255的有效值表示范围内)扩展原灰度图的大小,使得边缘的像素点也能够使用同一模板计算。

核心需要一个能够统计矩阵中不为-1个数的表达式,形如[cnt,~]=size(sum(convM(convM~=(-1)),3));其中cnt为矩阵convM中不为(~=)-1的个数。

边缘处理函数

%% 空域平滑滤波中值平均
% Function:将灰度图grayImg与模板卷积
% n: 卷积核大小,默认为3x3。范围>=3,且为奇数,偶数则进行2*n+1处理
% way: 图像处理方式,0为直接截去边缘,1为对边缘进行较小模板的处理
% Date:2020/10/7
% Author:leezeeyee
function meanImg=spaceG1np(grayImg,n)
if nargin<2
    n=3;
end
% 输入有误处理
if mod(n,2)==0 || n==1
    n=n*2+1;
    print('n 为>=3的奇数,取n=n*2+1');
end
% 边缘保留值
keep=(n-1)/2;
% 边缘保留,预先*n^2
[M,N]=size(grayImg);
% 拓展原灰度图
processImg=-1*ones(M+n-1,N+n-1);
processImg(keep+1:M+keep,keep+1:N+keep)=grayImg;
meanImg=uint16(size(grayImg));
for row=1:M
    for col=1:N
%         通过对0的计算,得知此像素点周围的有效像素点个数(非-1)
        convM=processImg(row:row+2*keep,col:col+2*keep);
        [cnt,~]=size(sum(convM(convM~=(-1)),3));
        meanImg(row,col)=sum(convM,'all')/cnt;
    end
end
meanImg=uint8(meanImg);
end

最终效果

可见,此时边缘的噪声也得到了一定程度的去除。

参考文章

Leave a comment

Your email address will not be published. Required fields are marked *