zoukankan      html  css  js  c++  java
  • 数字图像处理之几种滤波器

    在图像增强中,平滑是为了消除图像中噪声的干扰,或者降低对比度,与之相反,有时为了强调图像的边缘和细节,需要对图像进行锐化,提高对比度。

    图的边缘是指在局部不连续的特征。

    简要介绍一下原理:

            拉普拉斯锐化图像是根据图像某个像素的周围像素到此像素的突变程度有关,也就是说它的依据是图像像素的变化程度。我们知道,一个函数的一阶微分描述了函数图像是朝哪里变化的,即增长或者降低;而二阶微分描述的则是图像变化的速度,急剧增长下降还是平缓的增长下降。那么据此我们可以猜测出依据二阶微分能够找到图像的色素的过渡程度,例如白色到黑色的过渡就是比较急剧的。

            或者用官方点的话说:当邻域中心像素灰度低于它所在的领域内其它像素的平均灰度时,此中心像素的灰度应被进一步降低,当邻域中心像素灰度高于它所在的邻域内其它像素的平均灰度时,此中心像素的灰度应被进一步提高,以此实现图像的锐化处理。

    应用:

             运用拉普拉斯可以增强图像的细节,找到图像的边缘。但是有时候会把噪音也给增强了,那么可以在锐化前对图像进行平滑处理。

    下面我们来推导二阶微分与像素的关系:

           先看一阶偏微分和推出的二元函数微分:

    一阶微分法能够用来检测边缘是否存在。

    那么二阶微分法,也就是拉普拉斯算子就可以确定边缘的位置。(有的文章中称下式为拉普拉斯掩膜中心系数)

    这样可以找到一个模板矩阵:

    这个成为四邻域也就是上面的二阶微分法

    这个是八邻域。

    【注】从上面的两种模板中就可以看出,如果一个黑色平面中有一个白点,那么模板矩阵可以使这个白点更亮。由于图像边缘就是灰度发生跳变的区域,所以拉普拉斯模板对边缘检测很有用。

    八邻域的表示法为:

    将算得的值替换原(x,y)处的像素值,可以得到类似边界的地方,然后根据下式得到锐化图像:

    注:上述文字及图片引用自:http://blog.csdn.net/zb1165048017/article/details/49330171     (博主写的很用心!orz)

    这里贴上笔者的拉普拉斯代码:

     1 a=imread('yue.jpg');
     2 a=rgb2gray(a);
     3 %figure,imshow(a);
     4 c=[443  602];
     5 c=a;
     6 for j=2:601
     7     c(1,j)=a(1,j-1);
     8     c(443,j)=a(441,j-1);
     9 end
    10 for i=2:442
    11     c(i,1)=a(i-1,1);
    12     c(i,602)=a(i-1,600);
    13 end
    14 subplot(1,2,1);
    15 imshow(c);
    16 for i=2:442
    17     for j=2:601
    18         lpls=8*c(i,j)-c(i-1,j-1)-c(i-1,j+1)-c(i+1,j-1)-c(i+1,j+1)-c(i-1,j)-c(i+1,j)-c(i,j-1)-c(i,j+1);
    19         if lpls<0
    20             a(i-1,j-1)=a(i-1,j-1)-lpls; %加上a(i-1,j-1),就是拉普拉斯增强滤波器。
    21         else
    22             a(i-1,j-1)=a(i-1,j-1)+lpls;
    23         end
    24     end
    25 end
    26 subplot(1,2,2);
    27 imshow(a);

    黑白图左边为未处理的原图,黑白图右边的为已处理的图片。

    上述为拉普拉斯滤波器。属于线性空间滤波器。

    下面讲述非线性空间滤波器:

    主要是排序滤波器

    比如 :最大值滤波器、最小值滤波器、中值滤波器。

    其中中值滤波器要注意的一个就是要滤波器的m*n必须为奇数

    本次对最大值滤波器的实现进行试验:

    最大值滤波器顾名思义就是在 f(x,y) 的领域中用最大的像素值代替 f(x,y) 的像素值。

    有了拉普拉斯滤波器构造的经验,我们很容易就写出最大值滤波器的代码

    ps:为了使最大值滤波器的效果更直观,我们用一张加了高斯噪声的图片来测试。

    代码:

     1 a=zeros(500,600);
     2 a=imnoise(a,'gaussian',0,0.03);   %将均值0,方差为0.03的高斯噪声加到图像a上
     3 subplot(1,3,1);
     4 imshow(a);
     5 %中值滤波器,调用medfilt函数。 
     6 b=medfilt2(a,[3,3]);
     7 subplot(1,3,2);
     8 imshow(b);
     9 %最大值滤波器,具体实现原理操作如下。
    10 c=[502  602];  
    11 c=a;
    12 for j=2:601
    13     c(1,j)=a(1,j-1);
    14     c(502,j)=a(500,j-1);
    15 end
    16 for i=2:501
    17     c(i,1)=a(i-1,1);
    18     c(i,602)=a(i-1,600);
    19 end
    20 for i=2:501
    21     for j=2:601
    22         mx=c(i,j);
    23         for x=-1:1
    24             for y=-1:1
    25                 if mx<c(i+x,j+y) 
    26                     mx=c(i+x,j+y);   
    27                 else continue;
    28                 end
    29             end
    30         end
    31         a(i-1,j-1)=mx;
    32     end
    33 end
    34 subplot(1,3,3);
    35 imshow(a);

    左边为初始图片,中间为中值滤波器滤波后的图像,右边为最大值滤波器滤波后的图片。

    我们很明显的看到右图噪声放大了,中间的图片噪声大大减弱。

    如果我们是白底黑色的噪声。那么最大值滤波器会过滤噪声。在这里就不继续试验了。

    中值滤波器,它能滤波椒盐噪声、高斯噪声等,并且相对于均值滤波器来说,它不仅能过滤噪声,而且还不会模糊边界,保护了图像尖锐的边缘。

    均值滤波器

    均值滤波器也是可以去除噪声比较好的一种方法,是把每个像素都用周围的8个像素来做均值操作,幅值近似相等且随机分布在不同位置上,这样可以平滑图像,速度较快,算法简单。但是无法去掉噪声,只能微弱的减弱它。

    具体实现代码如下:

    (ps:我不知道为什么循环写不行,我发现赋给每个像素点的最大值是28,在原图像中明明可以找到比这更大的像素点,但是不知道为什么赋不了,问题仍待解决中,有知道的可以在评论区留言,谢谢~)

     1 a=imread('diqiu.jpg');
     2 %subplot(1,3,1);
     3 %imshow(a);
     4 a=rgb2gray(a);
     5 c=filter2(fspecial('average',3),a)/255;
     6 % for i=2 : 1199
     7 %     for j=2 : 1071
     8 %         sum=0;
     9 %         for n=-1 : 1
    10 %             for m=-1 :1
    11 %                 sum=sum+a(i+n ,j+m);
    12 %             end
    13 %         end
    14 %         c(i , j)=sum/9;
    15 %     end
    16 % end
    17 subplot(1,2,2);
    18 imshow(c);
    19 subplot(1,2,1);
    20 imshow(a);

    效果图:

    梯度算子锐化滤波器

    梯度算子锐化滤波器有三种,分别是:Soble算子、Roberts算子、Prewitt算子。

    上课没有认真听,先把别人将的贴过来:http://blog.csdn.net/tonyshengtan

    http://blog.csdn.net/u012808193/article/details/45722283

    上述的三个梯度算子是图像边缘检测的经典算子

    代码:

    a=imread('diqiu.jpg');
    a=rgb2gray(a);
    figure,imshow(a);
    a=double(a);
    sobel=edge(a,'Sobel');
    roberts=edge(a,'Roberts');
    prewitt=edge(a,'Prewitt');
    figure,imshow(sobel), title('sobel');
    figure,imshow(roberts),title('roberts');
    figure,imshow(prewitt),title('prewitt');

    效果图:

    效果图符合我们预期的效果,即原图像的大部分边界都提取出来了!



  • 相关阅读:
    ffmpeg 合并文件
    win10 设备摄像头,麦克风,【隐私】权限
    负载均衡,过载保护 简介
    《用Python做科学计算》 书籍在线观看
    Getting Started with OpenMP
    Algorithms & Data structures in C++& GO ( Lock Free Queue)
    PostgreSQL新手入门
    Ubuntu 网络配置
    QT 4.7.6 驱动 罗技C720摄像头
    使用vbs脚本添加域网络共享驱动器
  • 原文地址:https://www.cnblogs.com/ISGuXing/p/7654572.html
Copyright © 2011-2022 走看看