中值滤波

中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值.中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。方法是用某种结构的二维滑动模板,将板内像素按照像素值的大小进行排序,生成单调上升(或下降)的为二维数据序列。二维中值滤波输出为g(x,y)=med{f(x-k,y-l),(k,l∈W)} ,其中,f(x,y),g(x,y)分别为原始图像和处理后图像。W为二维模板,通常为3*3,5*5区域,也可以是不同的的形状,如线状,圆形,十字形,圆环形等。

以3*3的滤波窗口为例:

中值滤波就是在3*3中的像素中寻找中值。 来看这样一个描述图(不然无图无真相)

这把可以清晰地看到, 这里有6,2,0,3,97,4,19,3,10这些像素, 然后中间的这些像素值就被这些像素的中位数也就是中值取代了。为了满足和前面一篇文章的格式相对应, 我们马上进入下一个单元, 来看看在平滑和降噪方面的功效!

原图1                                                                           中值滤波之后

 

噪声图(5%)                                                                中值滤波后:

 

很明显中值滤波不仅使得图像变得平滑(也可以理解为图像变得模糊了),但是其对去除了椒盐噪声特别有效,因为中值滤波就是专门针对去除孤立点噪声孕育为生的。从这里中值的逻辑来看, 我们做中值操作的时候, 那么白色(接近255的像素点)和黑色(接近0的像素)因为在窗口排序时是最大最小值, 除非周围的颜色都是黑色或者白色,不然一般都会被剔除掉,所以,一般来说这个中值滤波是去除椒盐噪声的非常理想的选择。

最后还是贴一段我运行的代码:

中值滤波
int media_filter(unsigned char* inbuffer, int width, int height, unsigned char* outbuffer)
{int mid=0;int winsize = 3;//滤波窗口大小int* windows = new int[winsize*winsize];int pos = (winsize - 1) / 2;memcpy(outbuffer, inbuffer, width*height);for (int m = pos; m < height - pos; m++){for (int n = pos; n < width - pos; n++)//(m,n)是窗口中心位置{//提取winsize*winsize的数据进入滤波窗int winpos = 0;for (int i = -pos; i < (winsize - pos); i++)for (int j = -pos; j < (winsize - pos); j++)windows[winpos++] = inbuffer[(m + i)*width + n + j];//对滤波窗中的数据排序取中值sort(windows, winsize*winsize);mid = windows[(winsize*winsize)/2];outbuffer[m*width + n] = mid;}}//对边界进行处理//未被处理的地方均取被处理的最边界for (int k = 0; k < pos; k++)for (int l = pos; l < width - pos; l++)outbuffer[k*width + l] = outbuffer[pos * width + l];//1到pos这几行未被处理的边界数据,始终取被处理的最上边界一层像素for (int a = height - pos; a < height; a++)for (int b = pos; b < width - pos; b++)outbuffer[a*width + b] = outbuffer[(height - pos - 1)*width + b];for (int c = 0; c < pos; c++)for (int d = 0; d < height; d++)outbuffer[d*width + c] = outbuffer[d*width + pos];for (int e = width - pos; e < width; e++)for (int f = 0; f < height; f++)outbuffer[f*width + e] = outbuffer[f*width + width - pos - 1];delete[] windows;windows = NULL;return 0;
}

均值滤波

把每个像素都用周围的9个像素来做均值操作 ”, 比如说这里有一个例子:

非常明显的, 这个3*3区域像素的颜色值分别是5,3,6,2,1,9,8,4,7那么中间的1这个像素的过滤后的值就是这些值的平均值, 也就是前面的计算方法: (5+3+6+2+1+9+8+4+7)/9=5

一目了然。那么这个均值滤波器有什么用处呢?

主要还是平滑图像的用处, 有的图像的锐度很高,用这样的均值算法,可以把锐度降低。使得图像看上去更加自然,下面就有几幅图我们可以看出一些端倪:

原图:                                                                          原图均值滤波处理之后:

 

这里还是可以明显的感觉到不同的, 没有好坏之分,就是第二幅图片看上去更为平滑。 继续我们的问题, 那这里均值平滑是否具有去除噪声的功能呢? 我们搞来了椒盐噪声(就是随机的白点,黑点)来试试手:

噪声图(5%椒盐噪声):                         均值滤波平滑处理之后:

 

首先这里的噪声还是比较小的, 只有5%,从均值的效果来看的话, 我可以说几乎没有用,其实直观的想也可以判断, 因为这里的处理并没有剔除这些噪声点, 而只是微弱地降低了噪声,所以效果可以想见的。。

好吧, 最后的时候还是贴上一段处理的C++均值滤波算法代码:

均值滤波
int mean_filter(unsigned char* inbuffer, int width, int height, unsigned char* outbuffer)
{int mid=0;int winsize = 3;//滤波窗口大小int* windows = new int[winsize*winsize];int pos = (winsize - 1) / 2;memcpy(outbuffer, inbuffer, width*height);for (int m = pos; m < height - pos; m++){for (int n = pos; n < width - pos; n++)//(m,n)是窗口中心位置{//提取winsize*winsize的数据进入滤波窗int winpos = 0;for (int i = -pos; i < (winsize - pos); i++)for (int j = -pos; j < (winsize - pos); j++)windows[winpos++] = inbuffer[(m + i)*width + n + j];mid=getaverage(windows, winsize*winsize);//对滤波窗中的数据取平均值outbuffer[m*width + n] = mid;}}//对边界进行处理//未被处理的地方均取被处理的最边界for (int k = 0; k < pos; k++)for (int l = pos; l < width - pos; l++)outbuffer[k*width + l] = outbuffer[pos * width + l];//1到pos这几行未被处理的边界数据,始终取被处理的最上边界一层像素for (int a = height - pos; a < height; a++)for (int b = pos; b < width - pos; b++)outbuffer[a*width + b] = outbuffer[(height - pos - 1)*width + b];for (int c = 0; c < pos; c++)for (int d = 0; d < height; d++)outbuffer[d*width + c] = outbuffer[d*width + pos];for (int e = width - pos; e < width; e++)for (int f = 0; f < height; f++)outbuffer[f*width + e] = outbuffer[f*width + width - pos - 1];delete[] windows;windows = NULL;return 0;
}

一种改进的中值滤波(HMF)

在中值滤波器和均值滤波器之后, 这次看到是中值滤波器的改进, Hybrid Median Filter ,这个名字我实在不好把握,实在不知道翻译成什么比较妥当.只好沿用了混合动力车里面的混合二字, 姑且把这种滤波器命名为混合中值滤波器. 这个滤波器的工作流程较之原先有些繁琐, 来看看这张图

图截的有些模糊, 但是还是看出了大致的流程, 首先当前像素的上下左右和自身取中值1 , 然后左上右上左下右下和自身取中值2 完了前面的两个中值和当前像素值再取一次中值 , 得到的值就是最后的终极像素值了. 可以看到这个流程还是有些复杂的.. 那他的效果如何捏? 我们还是和前几次一样来观察一把:

原图:                                                      HMF之后:

 

噪声污染:                                                 HMF之后:

 

从前面的图片可以看到, 图片从高锐度经由混合中值滤波之后, 锐度下降了. 但是在去噪声的环节上, 这个所谓的混合中值滤波器表现的甚至不如中值滤波来的效果好, 当然因为这里的噪声是随机的, 可能有些因素在其中. 但从原理上分析.这种滤波器确实存在不能过滤掉的可能, 原因在什么地方呢? 且看我们这个大图中的一个小局部:

把图放大之后看的很清楚了, 在红色的圆圈圈出来的地方, 不出意外的发现了水平连续的3个白色像素. 再联想到我们之前经过HMF之后的效果图就不难得出结论, 就是者连续的3个点造成了最后的这个白色像素. 怎么说呢? 很简单, 在HMF的第一步过程中, 因为我们选择的点是5各点, 上下左右中, 那么经过计算, 就是白色无疑了, 不管第二步得到什么像素, 在第三步的时候, 让2个白色取中值, 肯定得到的白色像素了! 仔细想来确实是这个么道理.  但是median filter的时候因为要整体考虑9个像素的中值, 这里很有可能就不是白色了! 所以这个混合中值滤波器会在保持线条的边缘上有独到之处(因为比较容易保持联系像素的颜色不受伤害), 而消除噪声还是median filter表现更胜一筹.老规矩, 最后再贴一下处理的函数代码:

unsigned char median(unsigned char* elements, int width)
{  //   Order elements (only half of them)  for (int i = 0; i < (width >> 1) + 1; ++i)  {  //   Find position of minimum element  int min = i;  for (int j = i + 1; j < width; ++j)  if (elements[j] < elements[min])  min = j;  //   Put found minimum element in its place  unsigned char temp = elements[i];  elements[i] = elements[min];  elements[min] = temp;  }  //   Get result - the middle element  return elements[width >> 1];
}
/**
** method to remove noise from the corrupted image by hybrid median value
* @param corrupted input grayscale binary array with corrupted info
* @param smooth output data for smooth result, the memory need to be allocated outside of the function
* @param width width of the input grayscale image
* @param height height of the input grayscale image
*/
void hybridMedianFilter (unsigned char* corrupted, unsigned char* smooth, int width, int height)
{  memcpy ( smooth, corrupted, width*height*sizeof(unsigned char) );  for (int j=1;j<height-1;j++)  {  for (int i=1;i<width-1;i++)  {  unsigned char window[5];  unsigned char results[3];  //   Pick up cross-window elements  window[0] = corrupted[(j - 1) * width + i];  window[1] = corrupted[j * width + i - 1];  window[2] = corrupted[j * width + i];  window[3] = corrupted[j * width + i + 1];  window[4] = corrupted[(j + 1) * width + i];  //   Get median  results[0] = median(window, 5);  //   Pick up x-window elements  window[0] = corrupted[(j - 1) * width + i - 1];  window[1] = corrupted[(j - 1) * width + i + 1];  window[2] = corrupted[j * width + i];  window[3] = corrupted[(j + 1) * width + i - 1];  window[4] = corrupted[(j + 1) * width + i + 1];  //   Get median  results[1] = median(window, 5);  //   Pick up leading element  results[2] = corrupted[j * width + i];  //   Get result  smooth[j*width+i] = median(results, 3);  }  }
}

因为要取中值, 还附加了一个取中值的函数median

实验结果:

以下所有结果均为C++处理。
1,对原图像进行处理的结果
可以发现对边缘有就很好的保护能力:(左为原图)

2,对噪声图像进行处理的结果
注意这是matlab里面的椒盐噪声,最左边是噪声图像,中间是本文改进中值滤波(HMF)算法,最右边是自适应中值滤波。
去噪效果一般。椒盐是中值滤波系列最容易处理的噪声,可以见得该改进算法有它的不足之处,在椒盐噪声的处理效果上明显不如经典的自适应中值滤波!

中值滤波对噪声图像的效果,存在明显的不足(模糊效果):

参考资源:

【1】百度百科,http://baike.baidu.com/link?url=mQ37rozxl6jHqzdVY56zOO_tpSvInR0EA8AGK5W242ljIXOxPz_xtTT8Bgi8fOVocmp6XpiI1FK6byALfUir1a

【2】网友hhygcy,http://blog.csdn.net/hhygcy/article/details/4325462

注:本文是在原作者hhygcy基础上二次加工重写,代码有较大改动

数字图像处理,中值滤波和均值滤波及其改进算法的C++实现相关推荐

  1. 数字图像处理 中值滤波 MATLAB实验

    一.原理_中值滤波 中值滤波的基本思想是将图像中每个像素的灰度值用其邻域内像素灰度的中值代替,它是一种非线性平滑滤波算法. 设加噪图像为 f(x,y) ,经中值滤波处理后的图像为g(x,y) ,则: ...

  2. 数字图像处理——中值滤波降噪

    使用滤波模板中像素点的中值点作为目标像素,这就称为中值滤波降噪(顾名思义) Python实现过程如下: 图像数据为: 图像中存在典型的椒盐噪声,而中值降噪,对椒盐噪声的作用是非常有效的. 导入要使用的 ...

  3. 数字图像处理——中值滤波及其改进算法

    一.算法介绍 中值滤波器是非线性滤波器的一个例子,它在保留图像特征方面非常有效. 但是,滤波器的窗口大小直接影响中值滤波器的性能. 较小的窗口保留了特征,但会导致噪声抑制的减少. 在较大窗口的情况下, ...

  4. 数字图像处理——中值滤波中心加权中值滤波

    引言:在处理图像时,线性滤波将破坏边缘,而且不能有效滤除脉冲噪声.非线性滤波基于对输入信号序列的一种非线性映射关系,常可把某一特定的噪声近似映射为零而保留信号的重要特征,因而可以在一定程度上克服线性滤 ...

  5. 数字图像处理(修正的阿尔法均值滤波)

    修正的阿尔法均值滤波 统计排序滤波器的响应基于由该滤波器包围的图像区域中的像素值的排序,为一种非线性滤波器.常用的非线性滤波器有中值滤波器..自适应中值滤波.最大值(最小值)滤波器.中点滤波器与修正的 ...

  6. FPGA图像处理_中值滤波、均值滤波、极值滤波

    FPGA实现图像滤波(中值滤波.均值滤波.极值滤波) 前言 一.滤波原理 二.FPGA上Verilog实现步骤 1.图像周围填0 2.数据延迟 3.数据处理 总结 前言 首先介绍滤波原理,再附上ver ...

  7. 图像处理中的滤波器之均值滤波,中值滤波,高斯滤波

    1.均值滤波 原理: 均值滤波采用线性的方法,使用模板内所有像素的平均值代替模板中心像素灰度值 特点: 不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去 ...

  8. 均值滤波java_均值滤波,中值滤波,最大最小值滤波

    http://blog.csdn.net/fastbox/article/details/7984721 讨论如何使用卷积作为数学工具来处理图像,实现图像的滤波,其方法包含以下几种,均值 滤波,中值滤 ...

  9. python高斯滤波和降噪_python添加高斯噪声和椒盐噪声,实现中值滤波和均值滤波,实现Roberts算子和Sobel算子...

    写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验一,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验一. 由于时间紧张,代码没有进行任何优化, ...

  10. python设计---空域增强之图片去噪(中值滤波、均值滤波、高斯滤波、双边滤波)

    空域增强之图片去噪 引言 中值滤波及均值滤波 中值滤波 理论方法 均值滤波 中值滤波和均值滤波的对比 程序 高斯滤波 程序 双边滤波 程序 ui界面 设计程序 后续 引言 我们在日常工作生活中,总是需 ...

最新文章

  1. vue-cli启动本地服务,局域网下通过ip访问不到的原因
  2. 【Android 逆向】Android 系统文件分析 ( 外部存储设备文件 | sbin 命令程序目录 | dev 字符设备目录 )
  3. 【Servlet】Java Serlvet Listener 监听器
  4. 央行放水点燃房价,普通家庭如何理财?
  5. RS232与串口通信的4个注意事项详解
  6. git粘贴命令行_如何使用git检测复制和粘贴代码?
  7. vue项目token放在哪里_关于vue动态菜单的那点事
  8. vue获取table一列数据_vue表格含有一列多选框,如何获取被选中的行的数据?
  9. Java 核心五个类(File、Outputstream、Inputstream、Reader、Writer)一个接口(Serializable)...
  10. Kotlin入门(24)如何自定义视图
  11. mac java安全_关于 Java for Mac OS X 10.4 发行版 7 的安全性内容
  12. Qt总结之五:读写文件操作
  13. 搭建Sublime Text3 Java编译运行环境
  14. “CSIG 计算机视觉前沿 · 研讨会”于6月28日在百度举行
  15. 国内百兆独立服务器哪里的比较便宜镇江电信好吗
  16. 电能计量芯片HLW8110/HLW8112
  17. LLVM IRBuilder and pass:1.llvm基础命令
  18. 问题 E: 1.10 旅行时间  根据火车的出发时间和到达时间,编写程序计算整个旅途所用的时间。
  19. 北京到平谷石林峡旅游包车攻略
  20. c# 与 Access数据库 dataset操作

热门文章

  1. 三种简单的方法去除视频中的水印
  2. 用curve_fit拟合幂函数与excel拟合误差问题
  3. 从qire123上抓取bdhd下载地址的firefox extension
  4. [三星6818]gpio模拟spi信号编写门禁卡识别模块驱动
  5. 100句美文、150个哲理成语和9篇课本素材运用
  6. pyqt5 设置按钮圆角
  7. win10安装oracle18c,Win10 Oracle 18c 完全卸载
  8. Android 梯形进度条、下载进度条;
  9. SpringBoot+Vue实现前后端分离的财务管理系统
  10. 折腾6年高龄笔记本-宏碁E5-572G-57MX-加固态-解决磁盘自检-坏道