本文主要介绍了自适应的中值滤波器,并基于OpenCV实现了该滤波器,并且将自适应的中值滤波器和常规的中值滤波器对不同概率的椒盐噪声的过滤效果进行了对比。最后,对中值滤波器的优缺点了进行了总结。

空间滤波器

一个空间滤波器包括两个部分:

  • 一个邻域,滤波器进行操作的像素集合,通常是一个矩形区域
  • 对邻域中像素进行的操作

一个滤波器就是在选定的邻域像素上执行预先定义好的操作产生新的像素,并用新的像素替换掉原来像素形成新的图像。
通常,也可以将滤波器称之为核(kernel),模板(template)或者窗口(window)

根据预定义的操作,可以将滤波器分为:

  • 线性滤波器
  • 非线性滤波器

而根据滤波器最终对图像造成的影响,可以将滤波器分为:

  • 平滑滤波器 ,通常用于模糊图像或者去除图像中的噪声
  • 锐化滤波器,突出图像中的边缘细节部分

中值滤波器 Median Filter

中值滤波器是一种常用的非线性滤波器,其基本原理是选择待处理像素的一个邻域中各像素值的中值来代替待处理的像素,其主要功能是像素的灰度值与周围像素比较接近,从而消除孤立的噪声点,所以中值滤波器能够很好的消除椒盐噪声。不仅如此,中值滤波器在消除噪声的同时,还能有效的保护图像的边界信息,不会对图像造成很大的模糊(相比于均值滤波器)。

中值滤波器的效果受滤波窗口尺寸的影响较大,在消除噪声和保护图像的细节存在着矛盾:滤波窗口较小,则能很好的保护图像中的某些细节,但对噪声的过滤效果就不是很好;反之,窗口尺寸较大有较好的噪声过滤效果,但是会对图像造成一定的模糊。另外,根据中值滤波器原理,如果在滤波窗口内的噪声点的个数大于整个窗口内像素的个数,则中值滤波就不能很好的过滤掉噪声。

自适应中值滤波器 Adaptive Median Filter

上面提到常规的中值滤波器,在噪声的密度不是很大的情况下(根据经验,噪声的出现的概率小于0.2),效果不错。但是当概率出现的概率较高时,常规的中值滤波的效果就不是很好了。有一个选择就是增大滤波器的窗口大小,这虽然在一定程度上能解决上述的问题,但是会给图像造成较大的模糊。

常规的中值滤波器的窗口尺寸是固定大小不变的,就不能同时兼顾去噪和保护图像的细节。这时就要寻求一种改变,根据预先设定好的条件,在滤波的过程中,动态的改变滤波器的窗口尺寸大小,这就是自适应中值滤波器 Adaptive Median Filter。在滤波的过程中,自适应中值滤波器会根据预先设定好的条件,改变滤波窗口的尺寸大小,同时还会根据一定的条件判断当前像素是不是噪声,如果是则用邻域中值替换掉当前像素;不是,则不作改变。

自适应中值滤波器有三个目的:

  • 滤除椒盐噪声
  • 平滑其他非脉冲噪声
  • 尽可能的保护图像中细节信息,避免图像边缘的细化或者粗化。

自使用中值滤波算法描述

自适应滤波器不但能够滤除概率较大的椒盐噪声,而且能够更好的保护图像的细节,这是常规的中值滤波器做不到的。自适应的中值滤波器也需要一个矩形的窗口SxyS_{xy},和常规中值滤波器不同的是这个窗口的大小会在滤波处理的过程中进行改变(增大)。需要注意的是,滤波器的输出是一个像素值,该值用来替换点(x,y)(x,y)处的像素值,点(x,y)(x,y)是滤波窗口的中心位置。

在描述自适应中值滤波器时需要用到如下的符号:

  • Zmin=SxyZ_{min}=S_{xy}中的最小灰度值
  • Zmax=SxyZ_{max}=S_{xy}中的最大灰度值
  • Zmed=SxyZ_{med}=S_{xy}中的灰度值的中值
  • ZxyZ_{xy}表示坐标(x,y)(x,y)处的灰度值
  • Smax=SxyS_{max}=S_{xy}允许的最大窗口尺寸

自适应中值滤波器有两个处理过程,分别记为:A和B。
A :
A1 = Zmed−ZminZ_{med}-Z_{min}
A2 = Zmed−ZmaxZ_{med}-Z_{max}
如果A1 > 0 且 A2 < 0,跳转到 B;
否则,增大窗口的尺寸
如果增大后窗口的尺寸 ≤Smax\leq S_{max},则重复A过程。
否则,输出ZmedZ_{med}

B:
B1 = Zxy−ZminZ_{xy}-Z_{min}
B2 = Zxy−ZmaxZ_{xy}-Z_{max}
如果B1 > 0 且 B2 < 0,则输出ZxyZ_{xy}
否则输出ZmedZ_{med}

自适应中值滤波原理说明

过程A的目的是确定当前窗口内得到中值ZmedZ_{med}是否是噪声。如果Zmin<Zmed<ZmaxZ_{min} ,则中值ZmedZ_{med}不是噪声,这时转到过程B测试,当前窗口的中心位置的像素ZxyZ_{xy}是否是一个噪声点。如果Zmin<Zxy<ZmaxZ_{min} ,则ZxyZ_{xy}不是一个噪声,此时滤波器输出ZxyZ_{xy};如果不满足上述条件,则可判定ZxyZ_{xy}是噪声,这是输出中值ZmedZ_{med}(在A中已经判断出ZmedZ_{med}不是噪声)。

如果在过程A中,得到则ZmedZ_{med}不符合条件Zmin<Zmed<ZmaxZ_{min} ,则可判断得到的中值ZmedZ_{med}是一个噪声。在这种情况下,需要增大滤波器的窗口尺寸,在一个更大的范围内寻找一个非噪声点的中值,直到找到一个非噪声的中值,跳转到B;或者,窗口的尺寸达到了最大值,这时返回找到的中值,退出。

从上面分析可知,噪声出现的概率较低,自适应中值滤波器可以较快的得出结果,不需要去增加窗口的尺寸;反之,噪声的出现的概率较高,则需要增大滤波器的窗口尺寸,这也符合种中值滤波器的特点:噪声点比较多时,需要更大的滤波器窗口尺寸。

实现

有了算法的详细描述,借助于OpenCV对图像的读写,自适应中值滤波器实现起来也不是很困难。

    int minSize = 3; // 滤波器窗口的起始尺寸int maxSize = 7; // 滤波器窗口的最大尺寸Mat im1;// 扩展图像的边界copyMakeBorder(im, im1, maxSize / 2, maxSize / 2, maxSize / 2, maxSize / 2, BorderTypes::BORDER_REFLECT);// 图像循环for (int j = maxSize / 2; j < im1.rows - maxSize / 2; j++){for (int i = maxSize / 2; i < im1.cols * im1.channels() - maxSize / 2; i++){im1.at<uchar>(j, i) = adaptiveProcess(im1, j, i, minSize, maxSize);}}

首先定义滤波器最小的窗口尺寸以及最大的窗口尺寸。
要进行滤波处理,首先要扩展图像的边界,以便对图像的边界像素进行处理。copyMakeBorder根据选择的BorderTypes使用不同的值扩充图像的边界像素,具体可参考OpenCV的文档信息。
下面就是遍历图像的像素,对每个像素进行滤波处理。需要注意一点,不论滤波器多么的复杂,其每次的滤波过程,都是值返回一个值,来替换掉当前窗口的中心的像素值。函数adpativeProcess就是对当前像素的滤波过程,其代码如下:

uchar adaptiveProcess(const Mat &im, int row,int col,int kernelSize,int maxSize)
{vector<uchar> pixels;for (int a = -kernelSize / 2; a <= kernelSize / 2; a++)for (int b = -kernelSize / 2; b <= kernelSize / 2; b++){pixels.push_back(im.at<uchar>(row + a, col + b));}sort(pixels.begin(), pixels.end());auto min = pixels[0];auto max = pixels[kernelSize * kernelSize - 1];auto med = pixels[kernelSize * kernelSize / 2];auto zxy = im.at<uchar>(row, col);if (med > min && med < max){// to Bif (zxy > min && zxy < max)return zxy;elsereturn med;}else{kernelSize += 2;if (kernelSize <= maxSize)return adpativeProcess(im, row, col, kernelSize, maxSize); // 增大窗口尺寸,继续A过程。elsereturn med;}
}

首先,根据当前窗口的大小,取得所有像素值存放到vector中,然后对vector进行排序,取得像素的最小值、最大值和中值。然后测试当前取得的中值是否在(min,max)之间,如果是,则中值不是噪声点,则开始对当前像素值进行处理,判断其是否是噪声点。如果,测试当前已取得的中值是噪声点,则扩大窗口的尺寸,在更大的空间中重新寻找中值。

上面自适应中值滤波器实现起来比较简单,所以问题就来了:效率及其的低下。这里,这是对自适应中值滤波器的原理的学习,可以忽略这个不必要的细节。

结果对比


左边是添加概率为0.2的椒盐噪声,右边是原图。下面是使用常规的中值滤波和本文实现的自适应中值滤波器后的处理结果

左边是自适应中值滤波器(最小窗口为3,最大窗口为7)的结果,右图是常规中值滤波器(窗口大小为5)的结果。可以看出,无论是中值滤波还是自适应的中值滤波,都能过滤掉图像中的噪声,自适应中值滤波器的效果要好些,常规的还有一些噪声没有过滤掉。而且,常规的中值滤波器对图像造成的模糊较明显,而自适应中值滤波器很好的的保存了图像中的细节。

下面测试更大概率噪声下,两种滤波器的工作情况。噪声概率为0.4时,

可以看出,常规的中值滤波器已经不能很好的过滤掉噪声,而自适应的中值滤波还可以胜任。

中值滤波器总结

  • 中值滤波器能够很好的滤除“椒盐”噪声。椒盐噪声是在图像上随机出现的孤立点,根据中值滤波器的原理,使用邻域像素的中值代替原像素,能够有效的消除这些孤立的噪声点。
  • 和均值滤波器相比,中值滤波在消除噪声的同时,还能在很大程度保护图像的细节,不会造成很大的模糊。
  • 和常规的中值滤波器相比,自适应中值滤波器能够更好的保护图像中的边缘细节部分。

图像处理基础(2):自适应中值滤波器(基于OpenCV实现)相关推荐

  1. 图像处理(二)之 基于OpenCV的水泥裂缝检测(区域延申)

    一.基本逻辑思路 一.前期图像处理 1. 读取图形.修改尺寸.灰度图转换 # 读取图片origin = PreProcess.read_image("test_img/1.jpg" ...

  2. OpenCV基础(17)基于OpenCV、scikit-image和Python的直方图匹配

    在本教程中,您将学习如何使用OpenCV和scikit-image进行直方图匹配. 上周我们讨论了直方图均衡化,这是一种基本的图像处理技术,可以提高输入图像的对比度. 但是,如果你想自动匹配两幅图像的 ...

  3. [Python从零到壹] 三十三.图像处理基础篇之什么是图像处理和OpenCV配置

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  4. Android:基于OpenCV实现身份证识别(C++)——移植图像算法

    系列文章目录 第一章 Android:基于OpenCV实现身份证识别(C++)--图像处理 第二章 Android:基于OpenCV实现身份证识别(C++)--移植图像算法 文章目录 系列文章目录 前 ...

  5. 【youcans 的 OpenCV 例程 200 篇】101. 自适应中值滤波器

    欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中 [youcans 的 OpenCV 例程 2 ...

  6. OPENCV图像处理基础

    OPENCV图像处理基础 1.图像处理基础 1.1 数字图像 1.1.1 数字图像概念: 1.1.2 数字图像起源: 1.1.3 常见成像方式: 1.1.4 数字图像的应用: 1.1.5 Opencv ...

  7. [Python图像处理] 十四.基于OpenCV和像素处理的图像灰度化处理

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  8. 基于 opencv 的图像处理入门教程

    点击上方"算法猿的成长",关注公众号,选择加"星标"或"置顶" 总第 146 篇文章,本文大约 5000 字,阅读大约需要 20 分钟 前言 ...

  9. 使用opencv和python实现图像的智能处理pdf_机器学习:基于OpenCV和Python的智能图像处理...

    前言 图像处理又称为数字图像处理,是指对图像进行分析.加工和处理,使其满足视觉方面需求的一种技术,它也是信号处理在图像领域的一种重要应用.随着计算机技术.人工智能和思维科学研究的迅速发展,图像处理向更 ...

  10. OpenCV入门(三)快速学会OpenCV2图像处理基础(一)

    OpenCV入门(三)快速学会OpenCV2图像处理基础(一) 作者:Xiou 1.颜色变换cvtColor imgproc的模块名称是由image(图像)和process(处理)两个单词的缩写组合而 ...

最新文章

  1. struts1.x 错误之 java.lang.IllegalArgumentException: No bean specified
  2. spring扩展点四:SmartInitializingSingleton 补充
  3. Dynamic Rankings(整体二分)
  4. Steam游戏上架五:U3D连接Steamworks SDK制作成就系统
  5. 【你可能不知道的】 PICkit3 脱机烧写 program to go 模式
  6. php curl怎么设置cookie,curl php正确设置cookie
  7. 剑与家园服务器维护,《剑与家园》杀鸡取卵式运营 如何拯救短命的区服?
  8. 5个高质量简历模板网站,免费、免费、免费
  9. Python系列-Django-Ninja
  10. 输入行数,输出一个字母回文金字塔(c语言)
  11. 买卖股票的最佳时间含手续费的代码实现
  12. NLU误召问题解决绪论
  13. 解决FTP文件访问需要输入用户名和密码的问题
  14. android 二进制 xml,如何将XML转换为Android二进制XML
  15. 【北邮国院大二下】产品开发与营销知识点整理 Topic11
  16. Java SE day21_网络编程
  17. 模拟电路软件oracle,电子商务模拟教学平台
  18. Django-知识回顾做个小DEMO
  19. 完美解决【 Failed to clean project: Failed to delete XXX】
  20. Cadence的启动路径

热门文章

  1. win8优化(win8优化大师设置开始界面)
  2. c# json转对象
  3. 深度学习常见算法的介绍
  4. PHP将日期转换为时间戳方式,php日期转换为时间戳的方法
  5. python做马尔科夫模型预测法_Python 3 爬虫学习笔记 8 马尔科夫模型
  6. Linux修改hosts主机映射文件
  7. 《信号与系统》解读 前言:为什么要解读《信号与系统》?
  8. 智能家居通信协议科普,什么户型选择什么产品一文看懂
  9. mac 谷歌浏览器不能登录账号不能同步
  10. 关于输入法图标消失 只能输入英文 win10 语言选项 键盘那里显示 输入法仅桌面的解决办法