中值滤波是一种非线性的图像平滑方法,与均值滤波器以及其他线性滤波器相比,它能够很好地滤除脉冲噪声,同时又能够保护目标图像边缘。它是一种邻域运算,

类似于卷积,但计算的不是加权求和,而是把邻域中的像素按灰度级进行排序,然后选择该组的中间值作为输出像素值,中值滤波可定义为:

式中:g(x,y)和f(x-i,y-i)分别为输出和输入像素灰度值,W为模板窗口。窗W可以取线状、方形、十字形、圆形、菱形等。

中值滤波实现过程如上图所示。标准的中值滤波器都是由一个奇数大小尺寸的滑动窗组成,通常为3x3窗或5x5窗等。以3x3窗为例,该窗沿着图像数据的行

方向逐像素滑动,在每一次滑动期间内,方形窗中的所有像素按照灰度值被排序,这组数据中的中值作为输出,替代原来窗函数的中心位置像素的灰度值。

均值滤波和中值滤波的内容非常基础,均值滤波相当于低通滤波,有将图像模糊化的趋势,对椒盐噪声基本无能为力。中值滤波的优点是可以很好的过滤掉椒盐噪声,缺点是易造成图像的不连续性。在下面的代码中,中值滤波主要通过冒泡算法来实现。

含有椒盐噪声的

中值滤波的效果如下,可以看到,几乎完全去除了椒盐噪声。

均值滤波的效果如下,可以看出,椒盐噪声被处理成了小的气泡,同时图像变模糊:

1、什么是中值滤波?

中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制效果好,在抑制随机噪声的同时能有效保护边缘少受模糊。

中值滤波可以过滤尖峰脉冲。目的在于我们对于滤波后的数据更感兴趣。滤波后的数据保留的原图像的变化趋势,同时去除了尖峰脉冲对分析造成的影响。

以一维信号的中值滤波举例。对灰度序列80、120、90、200、100、110、70,如果按大小顺序排列,其结果为70、80、90、10O、110、120、200,其中间位置上的灰度值为10O,则该灰度序列的中值即为100。一维信号中值滤波实际上就是用中值代替规定位置(一般指原始信号序列中心位置)的信号值。对前面所举的序列而言,中值滤波的结果是用中值100替代序列80、120、90、200、100、110、70中的信号序列中心位置值200,得到的滤波序列就是80、120、90、100、100、110、70。如果在此序列中200是一个噪声信号,则用此方法即可去除这个噪声点。

二维中值滤波算法是:对于一幅图像的象素矩阵,取以目标象素为中心的一个子矩阵窗口,这个窗口可以是3*3 ,5*5 等根据需要选取,对窗口内的象素灰度排序,取中间一个值作为目标象素的新灰度值。窗口示例如ooooxoooo上面x为目标象素,和周围o组成3*3矩阵Array,然后对这9个元素的灰度进行排序,以排序后的中间元素Array[4]为x的新灰度值,如此就完成对象素x的中值滤波,再迭代对其他需要的象素进行滤波即可。

图像处理中,中值滤波的实现方法

1:通过从图像中的某个采样窗口取出奇数个数据进行排序

2:用排序后的中值取代要处理的数据即可

中值滤波的算法实现过程,重点是排序,最常用的冒泡排序~~

把滤波区间的数据从小到大进行排序,然后取中值,(如果是奇数个数据,那么中值就只有一个了,如果偶数个数据,中值有两个,可以对两个数据再求平均)

下面是一个C语言实现中值滤波的函数:

unsignedcharGetMedianNum(int* bArray,intiFilterLen)

{

inti,j;// 循环变量

unsigned charbTemp;

// 用冒泡法对数组进行排序

for(j = 0; j

{

for(i = 0; i

{

if(bArray[i] > bArray[i + 1])

{

// 互换

bTemp = bArray[i];

bArray[i] = bArray[i + 1];

bArray[i + 1] = bTemp;

}

}

}

// 计算中值

if((iFilterLen & 1) > 0)

{

// 数组有奇数个元素,返回中间一个元素

bTemp = bArray[(iFilterLen + 1) / 2];

}

else

{

// 数组有偶数个元素,返回中间两个元素平均值

bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;

}

returnbTemp;

}

注:bArray 是一个整形指针,我们传入的一般是一个数组,用来存储待排序的数据

iFilterLen 是滤波器的长度

用在图像处理中时,由于像素的取值范围是0~255,刚好是unsigned char的范围,所以函数的返回值是unsignedchar,如果我们要处理的数是float型,或其他类型,返回值也可以更改~~返回值是bTemp,也即是我们想得到的中值

下面是一个完整的C语言程序,用在图像处理中/*************************************************************************

* 函数名称:

*   MedianFilter()

* 参数:

*   int   iFilterH         - 滤波器的高度

*   int   iFilterW         - 滤波器的宽度

*   int   iFilterMX        - 滤波器的中心元素X坐标

*   int   iFilterMY        - 滤波器的中心元素Y坐标

* 说明:

*   该函数对DIB图像进行中值滤波。

************************************************************************/

#define iFilterW 1

#define iFilterH 1

#define iFilterMX 1

#define iFilterMY 1

#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)

unsigned charGetMedianNum(int* bArray,intiFilterLen);

voidMedianFilter(unsignedchar*pImg1,unsignedchar*pImg,intnWidth,intnHeight)

{

unsigned char*lpSrc;// 指向源图像的指针

unsigned char*lpDst;// 指向要复制区域的指针

intaValue[iFilterH*iFilterW];// 指向滤波器数组的指针

inti,j,k,l;// 循环变量

intlLineBytes;// 图像每行的字节数

lLineBytes = WIDTHBYTES(nWidth * 8);

for( i=0;i<>< span=""><>

(*pImg)=0;

// 开始中值滤波

// 行(除去边缘几行)

for(i = iFilterMY; i

{

// 列(除去边缘几列)

for(j = iFilterMX; j

{

// 指向新DIB第i行,第j个象素的指针

lpDst = pImg + lLineBytes * (nHeight - 1 - i) + j;

// 读取滤波器数组

for(k = 0; k

{

for(l = 0; l

{

// 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针

lpSrc = pImg1 + lLineBytes * (nHeight - 1 - i + iFilterMY - k) + j - iFilterMX + l;

// 保存象素值

aValue[k * iFilterW + l] = *lpSrc;

}

}

// 获取中值

* lpDst = GetMedianNum(aValue, iFilterH * iFilterW);

}

}

}

unsigned charGetMedianNum(int* bArray,intiFilterLen)

{

inti,j;// 循环变量

unsigned charbTemp;

// 用冒泡法对数组进行排序

for(j = 0; j

{

for(i = 0; i

{

if(bArray[i] > bArray[i + 1])

{

// 互换

bTemp = bArray[i];

bArray[i] = bArray[i + 1];

bArray[i + 1] = bTemp;

}

}

}

// 计算中值

if((iFilterLen & 1) > 0)

{

// 数组有奇数个元素,返回中间一个元素

bTemp = bArray[(iFilterLen + 1) / 2];

}

else

{

// 数组有偶数个元素,返回中间两个元素平均值

bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;

}

returnbTemp;

}

中值滤波的算法很多,但通常数据排序量较大。需要消耗大量时间,不利于图像处理的实时性。

(1)窗口大小为3*3的快速排序算法

为了便于说明。将3*3窗口内的各个像素分别定义为M11,M12,M13,M21,M22,M23,M31,M32,M33。

首先分别对窗口中的每一行计算最大值、中值、最小值,这样一共可以得到9个数值,分别包括3个最大值、3个中值、3个最小值:

第一行的最大值:Max1=max[M11,M12,M13];

第一行的中值:Med1=med[M11,M12,M13];

第一行的最小值:Min1=min[M11,M12,M13];

依此类推:

Max2=max[M21,M22,M23];Med2=med[M21,M22,M23];Min2=min[M21,M22,M23];

Max3=max[M31,M32,M33];Med3=med[M31,M32,M33];Min3=min[M31,M32,M33];

式中,max表示取最大值,med表示取中值,min表示取最小值。

难判断,9个数值中。3个最大值中的最大值和3个最小值中的最小值一定是9个像素中的最大值和最小值;3个中值中的最大值至少大于5个像素:即本行中的最

小值、其他2行的中值及最小值:而3个中值中的最小值至少小于5个素:即本行中的最大值、其他2行的中值及最小值。最后,比较3个最大值中的最小值

Min_of_Max,3个中值中的中值Med_of_Med,3个最小值中的最大值Max_of_Min.得到的中间值即为滤波的最后结果

Med_of_nine。具体过程表示如下:

Min_of_Max=min[Max1,Max2,Max3];

Med_of_Med=med[Med1,Med2,Med3];

Max_of_Min=max[Min1,Min2,Min3];

则最后滤波结果:

Med_of_nine=med[Min_of_Max,Med_of_Med,Max_of_Min];

利用这种排序法的中值滤波运算仅需17次比较,与传统算法相比。比较次数减少了近2倍,且该算法十分适用于在FPGA上做并行处理,大大提高了滤波的速度。

(2)窗口大小为5*5的快速排序算法

先看一个有5个元素的一维数组的排序方法

假设任意5个数为a,b,c,d,e。任意3个做比较,将会有三组每组10个输出,分别为

{max0,max1....max9};//10个

{med0,med1,.....med9};//10个

{min0,min1,min2.....min9};//10个

则有:max=MAX{max0,max1....max9};

med=MIN{max0,max1....max9}=MAX{min0,min1,min2.....min9};

submax=MAX{med0,med1,....med9};

submin=MIN{med0,med1.....med9};

min=MIN{min0,min1,min2.....min9};

1说明了采用本排序算法对5×5的图像窗口求取中值、最大值和最小值的步骤。图中的步骤(1)是把图1(a)5×5的图像窗口像素各列沿箭头方向作降幂排

列;步骤(2)接着把经过列降幂排列的每行像素沿箭头方向作行降幂排列,得到图1(d)的结果。在图1(d)中对各点数据在25个像素点中所处的位次进行

判断,可以得到如下的结论,其中:

m11为25个像素数据中的最小值,m55为25个像素数据中的最大值;

m12小于或等于其所在的原始列中的四个像素值和m13、m14、m15所在原始列的所有像素值(小于等于4+3×5=19个值),所以不可能为中值(中值排在第13位);

m13小于或等于其所在的原始列中的四个像素值和m14、m15所在原始列的所有像素值(小于等于4+2×5=14个值),所以不可能为中值;

m21小于或等于其所在的原始列中的三个像素值和m22、m23、m24、m25所在原始列的四个像素值(小于等于3+4×4=19个值),所以不可能为中值;

m22小于或等于其所在的原始列中的三个像素值和m23、m24、m25所在原始列的四个像素值(小于等于3+3×4=15个值),所以不可能为中值;

m31小于或等于其所在的原始列中的2个像素值和m32、m33、m34、m35所在原始列的三个像素值(小于等于2+4×3=14个值),所以不可能为中值;

m54大于或等于其所在的原始列中的四个像素值和m51、m52、m53所在原始列的所有像素值(大于等于4+3×5=19个值),所以不可能为中值;

m54大于或等于其所在的原始列中的四个像素值和m51、m52所在原始列的所有像素值(大于等于4+2×5=14个值),所以不可能为中值;

m45大于或等于其所在的原始列中的三个像素值和m41、m42、m43、m44所在原始列的四个像素值(小于等于3+4×4=19个值),所以不可能为中值;

m44大于或等于其所在的原始列中的三个像素值和m41、m42、m43所在原始列的四个像素值(小于等于3+3×4=15个值),所以不可能为中值;

m35大于或等于其所在的原始列中的2个像素值和m34、m33、m32、m31所在原始列的三个像素值(小于等于2+4×3=14个值),所以不可能为中值;

这样就排除掉12个值,不再参与下一级的比较。剩下的13个值通过步骤(4),沿图1(d)箭头所示对角线方向做降幂排列得到图1(e)的结果。在图1(e)中对各点数据在13个数据中所处的位次进行判断,可以得到如下的结论,其中:

D52至少大于或等于其所在的原始列中的2个像素值或1个像素值(如果D52原来位于m25的位置)和D43、D34、D25所在原始列的所有像素值(大于或等于2+2×3+2=10或1+3×3=10个值),所以不可能为中值(中值排在第7位);

D43至少大于或等于其所在的原始列中的2个像素值或1个像素值(如果D43原来位于m25的位置)和D34、D25所在原始列的所有像素值(大于等于2+1×3+2=7或1+2×3=7个值),所以不可能为中值;

D34至少大于或等于其原始位置左侧和上方的四个值,以及D25所在原始位置左侧和上方的四个值(至少大于等于4+4+1=9个值),所以不可能为中值;

D51至少大于或等于其原始位置上方的1个值(如果D51原来位于m51的位置)和D42、D33、D24、D15以及它们上方的所有像素值(至少大于等于1+7=8个值),所以不可能为中值;

D42至少大于或等于其原始位置上方或左侧的1个值(如果D42原来位于m51或m15的位置)和D33、D24、D15以及它们左侧和上方的所有像素值(至 少大于等于1+6=7个值),所以不可能为中值。

同理,也可以判断出D14至少小于或等于10个值;D23小于或等于7个值;D32小于或等于9个值;D15小于或等于8个值;D24小于或等于7个值,所以这几个像素点都不可能为中值;

这样就又排除掉10个值,不再参与下一级的比较。经过两步排除,剩余三个值D41、D33、D25,经过第(5)步,沿箭头方向的对角线作降幂排列,得到图1(f)的结果,中值N33就为25个像素的中值。  

c语言均值滤波步骤,关于中值滤波算法,以及C语言实现相关推荐

  1. c语言用一维数组做中值滤波,快速中值滤波及c语言实现

    快速中值滤波及c语言实现 学生姓名:刘勇学号: 6100410218 专业班级:数媒101 [摘要]本文讨论了用c语言在微机上实现中值滤波及快速算法,在程序设计的过程中充分考虑到程序运行的时间复杂度和 ...

  2. NR基础篇下——中值滤波、多级中值滤波、多级中值混合滤波、加权中值滤波、中值有理滤波

    上一篇分享了一些均值滤波相关的算法,均值滤波作为一种线性滤波器,在滤除噪声的同时也会导致边缘模糊问题.而且均值滤波对高斯噪声的效果很好,但是对于椒盐噪声的效果就很一般.但是中值滤波作为一种顺序滤波器, ...

  3. 均值滤波、中值滤波、混合中值滤波C++源码实例

    1.均值滤波 含义:把每个像素都用周围的8个像素来做均值操作 . 均值滤波器有什么用处呢? 主要还是平滑图像的用处, 有的图像的锐度很高,用这样的均值算法,可以把锐度降低.使得图像看上去更加自然.(只 ...

  4. matlab编程实现自适应均值滤波和自适应中值滤波

    matlab编程实现自适应滤波器 一.自适应均值滤波器 1. 原理部分: 2. 程序代码 3. 结果对比 二.自适应中值滤波 1. 原理部分 2.程序代码 3. 结果对比 一.自适应均值滤波器 1. ...

  5. python手写均值滤波锐化_中值滤波,均值滤波,锐化滤波原理

    1 北京理工大学珠海学院实验报告 ZHUHAI CAMPAUS OF BEIJING INSTITUTE OF TECHNOLOGY 班级 学号 姓名 指导教师 成绩 实验题目 实验时间 1. 题目概 ...

  6. python VTK(十五) ----图像平滑 均值滤波 高斯平滑 中值滤波 各向异性滤波

    均值滤波vtkImageConvolve #!/usr/bin/env python # -*- coding:utf-8 -*- import vtk reader = vtk.vtkJPEGRea ...

  7. java 中值滤波_matlab图像处理-中值滤波原理(示例代码)

    中值滤波原理 ??中值滤波本质上是一种统计排序滤波器.对于原图像中某点(i,j),中值滤波以该点为中心的邻域内的所有像素的统计排序中值作为(i,j)点的响应. ??中值不同于均值,是指排序队列中位于中 ...

  8. c++ openvc4.5.5 学习笔记(五)图像平滑滤波几种基本方法(平均滤波blur、高斯平滑滤波GaussianBlur、中值滤波medianBlur、双边滤波bilateralFilter )

    平滑,也称为模糊,是一种简单而经常使用的图像处理操作. 要执行平滑操作,我们将对我们的图像应用过滤器.最常见的滤波器类型是线性的,其中输出像素的值(i.e. g(i,j)),被确定为输入像素值的加权和 ...

  9. Opencv之图像滤波:5.中值滤波(cv2.medianBlur)

    之前介绍的均值滤波.方框滤波.高斯滤波,都是线性滤波方式.由于线性滤波的结果是所有像素值的线性组合,因此含有噪声的像素也会被考虑进去,噪声不会被消除,而是以更柔和的方式存在.这时使用非线性滤波效果可能 ...

最新文章

  1. DB2 9 使用拓荒(733 检讨)认证指南,第 2 部分: DB2 数据操作(6)
  2. HTTP-FLV直播初探-flv.js播放器使用实例
  3. 成功解决''g++' 不是内部或外部命令,也不是可运行的程序 或批处理文件
  4. HTML5 基础知识(三)
  5. 备份 CSDN 博客(上)
  6. 部署不能产生class文件的问题
  7. 关于单表5-10亿行记录如何快速查询的问题,欢迎童鞋们都进来讨论
  8. Apollo的基本概念和集成实战
  9. mysql数据库(1):连接与断开服务器
  10. SharePoint专家新闻轮转器WebPart----亲測力推之Web部件
  11. 智能AI机器人源码,电话机器人源码和系统部署运行环境freeswitch
  12. python随机密码生成代码大全_Python实现随机密码生成器
  13. print 设置纸张的高度_祝贺! 2020珠峰高程测量登山队成功登顶!用Python计算一张纸对折多少次会超过珠峰高度?...
  14. Android Studio开发(六)短距离无线通信——蓝牙通信
  15. 柠檬班性能测试day3_性能测试基础知识(0521)
  16. 微信又确定全新封号标准!触犯这几条底线将被永久封号,望周知
  17. 新媒体运营怎么推广?
  18. 用户画像 用户画像表
  19. 《海边的卡夫卡》阅读琐记
  20. 2022年七夕送女朋友什么礼物好?实用且好看的礼物推荐

热门文章

  1. Mingw编译x264库,在VS上使用
  2. 网页 移动应用 支付宝 支付功能
  3. 产生随机数 matlab 分布,matlab产生各种分布的随机数
  4. excel表格行宽列高怎么设置_excel怎么调整列宽行高:excel中如何快速调整多行列高和行宽...
  5. 电脑不正常,不正常关电脑会怎样
  6. 标准C 语言程序的源文件名的默认后缀,c语言源程序文件名的后缀是什么
  7. SimpleQQ – WebQQ 桌面端 基于----WebQQ 2.00内核
  8. 冲刺金三银四,自动化软件测试面试宝典合集(含答案)!
  9. strcpy()函数详解
  10. 熬汗旗新会中学2021高考成绩查询,关于给2021届高考生高考励志祝福语文案