1. 程式人生 > >關於中值濾波演算法,以及C語言實現

關於中值濾波演算法,以及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 語言