关于中值滤波算法,以及C语言实现

关于中值滤波算法,以及C语言实现

2017年04月06日 11:45:58

阅读数:1464

1、什么是中值滤波?

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

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

 
  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是一个噪声信号,则用此方法即可去除这个噪声点。

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

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

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

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

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

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

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

 
  1. unsigned char GetMedianNum(int * bArray, int iFilterLen)

  2. {

  3. int i,j;// 循环变量

  4. unsigned char bTemp;

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

  7. for (j = 0; j < iFilterLen - 1; j ++)

  8. {

  9. for (i = 0; i < iFilterLen - j - 1; i ++)

  10. {

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

  12. {

  13. // 互换

  14. bTemp = bArray[i];

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

  16. bArray[i + 1] = bTemp;

  17. }

  18. }

  19. }

  20.  
  21. // 计算中值

  22. if ((iFilterLen & 1) > 0)

  23. {

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

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

  26. }

  27. else

  28. {

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

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

  31. }

  32.  
  33. return bTemp;

  34. }

注:bArray 是一个整形指针,我们传入的一般是一个数组,用来存储待排序的数据 
iFilterLen 是滤波器的长度 
用在图像处理中时,由于像素的取值范围是0~255,刚好是unsigned char 的范围,所以函数的返回值是unsigned char,如果我们要处理的数是float型,或其他类型,返回值也可以更改~~返回值是bTemp,也即是我们想得到的中值

下面是一个完整的C语言程序

 
  1. /*************************************************************************

  2. * 函数名称:

  3. * MedianFilter()

  4. * 参数:

  5. * int iFilterH - 滤波器的高度

  6. * int iFilterW - 滤波器的宽度

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

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

  9. * 说明:

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

  11. ************************************************************************/

  12. #define iFilterW 1

  13. #define iFilterH 1

  14. #define iFilterMX 1

  15. #define iFilterMY 1

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

  17.  
  18.  
  19. unsigned char GetMedianNum(int * bArray, int iFilterLen);

  20. void MedianFilter(unsigned char *pImg1,unsigned char *pImg,int nWidth,int nHeight)

  21. {

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

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

  24. int aValue[iFilterH*iFilterW]; // 指向滤波器数组的指针

  25. int i,j,k,l; // 循环变量

  26. int lLineBytes; // 图像每行的字节数

  27. lLineBytes = WIDTHBYTES(nWidth * 8);

  28. for ( i=0;i<nWidth;i++,pImg++ )

  29. (*pImg)=0;

  30. // 开始中值滤波

  31. // 行(除去边缘几行)

  32. for(i = iFilterMY; i < nHeight - iFilterH + iFilterMY + 1; i++)

  33. {

  34. // 列(除去边缘几列)

  35. for(j = iFilterMX; j < nWidth - iFilterW + iFilterMX + 1; j++)

  36. {

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

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

  39.  
  40. // 读取滤波器数组

  41. for (k = 0; k < iFilterH; k++)

  42. {

  43. for (l = 0; l < iFilterW; l++)

  44. {

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

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

  47.  
  48. // 保存象素值

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

  50. }

  51. }

  52.  
  53. // 获取中值

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

  55. }

  56. }

  57.  
  58. }

  59.  
  60. unsigned char GetMedianNum(int * bArray, int iFilterLen)

  61. {

  62. int i,j; // 循环变量

  63. unsigned char bTemp;

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

  66. for (j = 0; j < iFilterLen - 1; j ++)

  67. {

  68. for (i = 0; i < iFilterLen - j - 1; i ++)

  69. {

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

  71. {

  72. // 互换

  73. bTemp = bArray[i];

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

  75. bArray[i + 1] = bTemp;

  76. }

  77. }

  78. }

  79.  
  80. // 计算中值

  81. if ((iFilterLen & 1) > 0)

  82. {

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

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

  85. }

  86. else

  87. {

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

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

  90. }

  91.  
  92. return bTemp;

  93. }

文章标签: C 语言

猜你喜欢

转载自blog.csdn.net/nie15870449223/article/details/81252655