MATLAB图像的中值滤波——手动滤波和medfilt2函数滤波

        本文还是书接上回,https://blog.csdn.net/weixin_44502554/article/details/126283957?spm=1001.2014.3001.5502

        前期的思路是准备在FPGA当中实现图像的中值滤波,所以先搭建一下MATLAB的仿真平台,就是在MATLAB中先实现一下,具体的流程再贴一下:

MATLAB图像的中值滤波——手动滤波和medfilt2函数滤波_第1张图片

         当然中值滤波就属于上图中图像处理这一块。接下来我们从中值滤波的作用、滤波原理、算法实现三个方面展开讲解。

一、中值滤波的作用

        中值滤波主要的作用还是平滑图像,去除图像中的噪点,比如椒盐噪声这类。(讲的比较笼统,具体的网上有大量的资料就不做赘述)

二、中值滤波的原理

        中值滤波可以通过模板的方式对一幅图像(彩色or灰度)进行处理。模板的大小常见的可以是3*3、5*5、7*7等,形象的可以看成模板在一幅图像中进行滑动处理,将图像框成无数个大小一样的模板。例如3*3的模板:

MATLAB图像的中值滤波——手动滤波和medfilt2函数滤波_第2张图片

 那在模板中是如何处理的呢?

        具体在模板中的处理其实理解起来很简单,名字叫中值滤波,顾名思义就是找中值,例如在一个3*3模板当中:

MATLAB图像的中值滤波——手动滤波和medfilt2函数滤波_第3张图片

         这个模板框出的像素值分别为8、10、7、5、4、6、9、8、5,那么它的中值就为7,注意是中间值不是平均值,然后用这个中值7代替模板的中心像素值4就完成了,接着模板继续在图像中滑动,替换掉一幅图像中所有的像素点(注意每个像素点都有对应的模板),把图像中每个像素点都替换成以它为中心的模板的中值。

        细心的同学可能就发现了,图像的四周边缘的像素点怎么用模板处理呢?其实这也是比较常见的问题,先提出两种解决方案:

1)零值填充。也就是在图像四周边缘填充零,也不需要填充太多,一边填充一行或一列,如果是3*3总共就需要填充两行和两列零值就可,这样就会使得边缘的像素点也能被模板框住且变成中心点可以进行中值替换处理。如果是5*5的模板就需要填充4行和4列零,依此类推,如图:

MATLAB图像的中值滤波——手动滤波和medfilt2函数滤波_第4张图片

         比如500*600大小的图像、模板为3*3,填充后就会变成502*602大小的图像,处理的时候需要注意一下。

2)映射填充。我们为了保留更多的图像信息可以使用这种方法,比如对于第一个像素点它的左上角是没有像素点的,那我们就以它为中心将它右下角的像素点映射到左上角进行填充。直接上图:

MATLAB图像的中值滤波——手动滤波和medfilt2函数滤波_第5张图片

 三、中值滤波算法实现-MATLAB

        前面讲的理论比较多,现在我们进行实战。提前声明下面的这段代码主要是参考:http://t.csdn.cn/oVLnO

        笔者对代码进行了部分的修改和优化,在参看的文章中提到了填充处理和填充函数padarray,但在代码实现中未使用到,导致在图像的四周边缘还是存在明显的噪点。

        本文代码的优化主要在于:去除了边缘的噪点,同时进行了裁剪只保留了原始图像的像素大小

虽然比较简单,但是还是解释一下,代码大致可以分为三段:

        第一段代码主要是利用imread函数读取演示图像,设置模板的大小,然后获得图像的行列大小以及图层数,同时利用imnoise函数给图像加上椒盐噪声,最后利用imshow函数显示图像。

clear all;
close all;
img=imread('1.jpg');%读取原始图像
N=3;    %设置模板大小模板大小,值越大图像越模糊
[row, col, hight]=size(img);   %获取图像的行列和图层
figure;
imshow(img);%显示原图
img = imnoise(img,'salt & pepper'); %加入椒盐噪声
figure;
imshow(img); %显示加入噪声后的图片

原始图像:

MATLAB图像的中值滤波——手动滤波和medfilt2函数滤波_第6张图片

 加噪图像:

         第二段代码也是核心代码:

        首先对图像进行了填充,采用的方式是利用padarray函数进行零值填充,对四周边缘都填充了一行或一列。接着实现模板的滑动处理,主要是利用for扫描,分图层、分行、在一行中滑动滤波,找到每一个模板块,然后用到了median函数直接取一行数的中值,接着进行替换,最后当所有图层都遍历完成后进行裁剪还原图片的原始大小。

% //手动中值滤波/
img1 = padarray(img,[1,1]); %对图像边缘进行填充
for h=1:hight
    for i=1:row-N+1+2
        for j=1:col-N+1+2  
            c=img1(i:i+(N-1),j:j+(N-1),h); %在x1中从头取模板大小的块赋给c  
            e=c(1,:);      %e中存放是c矩阵的第一行  
            for u=2:N  %将c中的其他行元素取出来接在e后使e为一个行矩阵 
                e=[e,c(u,:)];          
            end  
            mid=median(e);      %取一行的中值  
            img1(i+(N-1)/2,j+(N-1)/2,h)=mid;   %将模板各元素的中值赋给模板中心位置的元素  
        end  
    end 
    img2(:,:,h)=img1(2:row+1,2:col+1,h);%对图像进行裁剪
end
figure;
imshow(img2);  %显示滤波后图片

滤波后图像:

MATLAB图像的中值滤波——手动滤波和medfilt2函数滤波_第7张图片

 图像边缘:

        可以看到成功去除了椒盐噪声,同时在图像边缘的椒盐噪声也成功去除了.

        仔细看大家还可以看到图像变的模糊了,这种模糊感是真真切切的,因为我们在对图像处理的时候,其实丢掉了大部分的图像像素点也就是图像信息,这就是导致模糊的主要原因,无法避免。

        最后一部分代码就比较简单,是MATLAB自带的中值滤波函数的使用,不再过多的叙述,需要注意的是在利用medfilt2函数直接对图像中值滤波时,需要图像先利用medfilt2函数转化为灰度图像,这对于我们追求色彩观感的同学来说还是有一部分影响。

整套的代码如下:

clear all;
close all;
img=imread('1.jpg');%读取原始图像
N=3;    %设置模板大小模板大小,值越大图像越模糊
[row, col, hight]=size(img);   %获取图像的行列和图层
figure;
imshow(img);%显示原图
img = imnoise(img,'salt & pepper'); %加入椒盐噪声
figure;
imshow(img); %显示加入噪声后的图片
% //手动中值滤波/
img1 = padarray(img,[1,1]); %对图像边缘进行填充
for h=1:hight
    for i=1:row-N+1+2
        for j=1:col-N+1+2  
            c=img1(i:i+(N-1),j:j+(N-1),h); %在x1中从头取模板大小的块赋给c  
            e=c(1,:);      %e中存放是c矩阵的第一行  
            for u=2:N  %将c中的其他行元素取出来接在e后使e为一个行矩阵 
                e=[e,c(u,:)];          
            end  
            mid=median(e);      %取一行的中值  
            img1(i+(N-1)/2,j+(N-1)/2,h)=mid;   %将模板各元素的中值赋给模板中心位置的元素  
        end  
    end 
    img2(:,:,h)=img1(2:row+1,2:col+1,h);%对图像进行裁剪
end
figure;
imshow(img2);  %显示滤波后图片
% ///matlab自带函数medfilt2中值滤波
img_gray=rgb2gary(img); %灰度处理,转化为二维矩阵
mid_img=medfilt2(img_ray,[N,N]);
figure;
imshow(mid_img);  %显示滤波后图片

-----------------------------------------------------分界线------------------------------------------------------------------

        做MATLAB和FPGA联合实现图像处理的方法,其实都比较适合FPGA工程师门入门且提高兴趣,大家把MATALB当成工具能用会用就行。希望有兴趣的小伙伴们把之前的文章也看看,后面我应该会在闲暇的时候把这个中值滤波系列做完,后面一章应该就是FPGA对中值滤波的实现。

你可能感兴趣的:(MATLAB,图像处理,matlab,图像处理)