天天看點

濾波器開發之五:基于算術平均的限幅濾波器

  通過AD采集資料時,我們總是希望采集到的資料是純淨而真實的,而實際上環境中存在太多的幹擾信号,為了讓我們得到的資料盡可能地接近實際值,我們需要降低這些幹擾信号的影響。是以軟體實作的數字濾波器應運而生,這一篇我們就來讨論基于中值算術平均的平滑濾波器。

1、問題的提出

  在我們通過AD采集擷取資料時,不可避免會受到幹擾信号的影響,而且很多時候我們希望盡可能的将這種影響減到最小。為實作這一目的,人們想了很多辦法,有硬體方面的,也有軟體方面的。在硬體難以改變或者軟體能夠達到相應效果時,我們一般采用軟體方法來實作,通常稱之為數字濾波。

  前面我們實作了基于算術平均的中值平均濾波器。這一濾波器可以解決我們一定頻率範圍内的周期性幹擾和随機性的高頻幹擾。但是随機性的幹擾出現的頻次我們是不知道的,是以我們采用去掉固定數量的極大值和極小值時,雖然可以去除掉随機幹擾的部分影響,但有兩種情況還是會對我們的最終計算産生影響。其一是當随機幹擾很頻繁,我們去掉固定數量的極大值和極小值時,還會有一些受幹擾的資料影響到最後的結果。其二是當随機幹擾不頻繁時,我們去掉固定數量的極大值和極小值就可能會去掉一些周期幹擾所影響的資料,那麼我們采用平均值的方法就不能很好的消除周期性幹擾的影響。

  為了消除上述兩種情況造成的影響,我們需要改進前述的基于算術平均的中值濾波算法。我們注意到我們的每一次的測量與上一次的測量相距時間很短,資料不會有大幅度的變化,超過一定幅度的資料我們就可以認為它是受到幹擾的資料,去除這些受到幹擾的資料,我們就可以得到相對理想的結果。

2、算法設計

  前面我們已經描述了問題的來源,這個問題分為兩個層次。第一,我們需要去除不同種類的幹擾信号,是以我們必須設計一個針對多種幹擾信号的濾波算法。第二,我們需要為丢棄固定數量極大值和極小值,而造成的周期幹擾的影響不平衡,導緻的算術平均算法不能完全消除周期幹擾。

  對于第一個層面的問題,其實與上一篇中所描述的問題是一緻的。我們知道主要的幹擾信号是相對頻率較低的周期幹擾和相對頻率較高的非周期幹擾,我們将分析這兩種信号的特點并針對性的采取相應的濾波手段。

  首先我們來考慮相對頻率較低的周期幹擾,這種幹擾來自于環境并且很難避免,但這種幹擾信号具有一定的規律,是以它對正常信号造成的影響也是有一定規律的。我們可以圖示如下:

濾波器開發之五:基于算術平均的限幅濾波器

  如果隻存在這一種周期性的低頻率的幹擾信号,那麼我們很容易想到采用算術平局算法就能夠去除,在前面我們也确實是這麼做的。事實上如果存在多種頻率的周期性幹擾信号,隻要采集到的資料樣本數量足夠,采用算數平均算法基本都是可以得到比較理想的結果。在我們的項目中,我們的采集頻率達到了1KHz,而我們每100毫秒出一個數,是以從理論上講,10Hz以上的周期性幹擾都可以通過算術平均率波來消除。

  接下來我們來考慮相對頻率較高的非周期幹擾,這種幹擾具有較大的随機性,有可能對信号的影響較大,也有可能對信号的影響較小,其頻率和幅值都是随機的,測量結果存在很大的偶然性。我們可以簡單的圖示如下:

濾波器開發之五:基于算術平均的限幅濾波器

  對于這種幹擾我們前面的方法對它是沒有效果的,但我們的ADC采用的是積分方式來檢測信号的,是以在兩個采樣點之間,無論這類幹擾信号在何時出現都會疊加到緊接着的這個采樣資料上,緻使最終的采樣資料比周期性幹擾疊加的情況下要麼大一些,要麼小一些。這就存在兩種情況,如果是正向幹擾就會是資料變大一些,如果是反向幹擾就會是資料變小一些。使得最終的測量資料更加背離原始資料或者更加接近原始資料。

  對于更加接近我們需要的資料的變化,我們先不用理會它,畢竟它更加接近我們想要的資料。對于更加偏離的那一部分資料,我們有什麼辦法将其去除掉呢?辦法是有的,我們借鑒比賽積分中去掉偶然性的方式,去掉最高和最低的數,中間的數應該更接近與真實值。具體如下圖所示:

濾波器開發之五:基于算術平均的限幅濾波器

  這樣去掉最大的一些數和最小的一些數後,并不能保證得到的就是真實的信号值,但有一點我們時刻以肯定的就是,餘下的值都更為接近真實的信号值。然後我們在對餘下的數采取算術平均操作,得到的就是接近真實值的一個采集值了。

  而對于第二個層面的問題,我們考慮到我們的測量對象并不會在兩次測量之間發生劇烈的變化,是以如果某一個原始資料與上一次的測量結果偏離較大,我們就認為它是一個受到了幹擾的資料,我們就将其舍棄。也就是說,以上一次的測量結果為基礎,超過上限或者下線的資料我們都認為是異常資料,具體操作圖示如下:

濾波器開發之五:基于算術平均的限幅濾波器

  事實上,這一算法不僅可以剔除劇烈變化的異常資料,對于超長周期的幹擾也會有一定的抑制作用。

3、編碼實作

  上一節,我們描述了基于算術平均的限幅濾波算法,接下來我們看看具體該如何實作這一算法。根據前述的經驗,我們可以将算法的實作分為三個層次:第一,采集到足夠多的資料,并将資料排序;第二,将資料中一定數量的極大值和極小值剔除;第三,将超越限幅值的資料剔除并使用算術平均值得到最後結果。

  首先來考慮資料采集和排序的問題。資料采集速度不能太低,資料量必須達到一定的資料,約幾十至幾百的規模。考慮到資料的規模,我們依然采用簡單直接的冒泡排序實作資料的極大值和極小值的查找。

  其次我們考慮剔除極大值和極小值的問題。我們實作了對資料的排序後,剔除極大值和極小值是非常容易的,關鍵是提出的數量怎麼設定。

  最後我們考慮限幅濾波的問題。我們将其超過限幅值的資料去除,并對餘下的資料取算術平均。這裡存在一個問題,就是如果超出限幅的資料量非常之多,遠遠超過了沒有超限的資料量該怎麼辦呢?我們認為這使得資料也許真的是因為某些原因而出現了較大的變化。此時我們将對全體資料取算術平均值,以快速響應檢測對象的變化。

  根據上述的描述,我們可以實作算法如下:

/*限幅平均濾波算法*/
static uint32_t LimitedMeanFilter(uint32_t *pData,uint16_t aSize,uint16_t eSize,uint32_t rData,uint32_t lValue)
{
  uint32_t tData;
  uint32_t uResult=0;
  uint32_t mResult=0;
  uint32_t lResult=0;
  uint16_t uNumber=0;
  uint16_t mNumber=0;
  uint16_t lNumber=0;
  
  if(aSize<=2*eSize)
  {
     return 0;
  }
  
  for (int i=0; i<aSize-1; i++) //比較n-1輪
  {
     for (int j=0; j<aSize-1-i; j++) //每輪比較n-1-i次,
     {
       if (pData[j] < pData[j+1])
       {
         tData = pData[j];
         pData[j] = pData[j+1];
         pData[j+1] = tData;
       }
     }
  }
  
  for(int j=eSize;j<(aSize-eSize);j++)
  {
     if(pData[j]>(rData+lValue))
     {
       uResult=uResult+pData[j];
       uNumber++;
     }
     else if(pData[j]<(rData-lValue))
     {
       lResult=lResult+pData[j];
       lNumber++;
     }
     else
     {
       mResult=mResult+pData[j];
       mNumber++;
     }
  }
  
  if((mNumber>uNumber)&&(mNumber>lNumber))
  {
     mResult = mResult/mNumber;
  }
  else
  {
     mResult = (uResult+mResult+lResult)/(uNumber+mNumber+lNumber);
  }
  
  return mResult;
}
           

  在上述實作中,我們先對輸入的資料進行了排序。然後我們去除了一定數量的極大值和極小值,并檢測餘下的值是否超越了限幅值。并對限幅之内、超越上限及超越下限的資料分别求和。然後判斷三類資料的數量,當限幅内資料的數量超過三分之一時,對其取算術平均,否則對所有資料取算術平均。

  對于函數中的五個參數:uint32_t *pData是需要濾波的原始采集資料;uint16_t aSize是需要濾波的原始采集資料的數量;uint16_t eSize是需要丢棄的極大值和極小值的數量。其中aSize要遠大于eSize的2倍,否則大部分被舍棄,濾波的意義就不大了。uint32_t rData參數是參考值;uint32_t lValue參數是偏離參考值的限幅。

  函數的使用也很簡單。比如在我們的應用中,我們以1KHz的速度采集原始值,每采集100個數出一個測量結果,去掉10個極大值和10個極小值,于是我們就可以調用函數如下:

temp[i]=LimitedMeanFilter(rDatas[i],100,10,refData[aPara.phyPara.waveband][i],150);
           

  在這個應用中,我們測試去掉10個極大值和10個極小值,并将限幅的偏差設定為了150,當然這些數值的取值根據具體的應用而定。特别是參考資料的選擇非常關鍵,一般可以根據不同的情況選取上一個測量結果、一定數量的之前的測量結果的算術平均或權重平均,或者采用累計的平均值等。

4、應用總結

  這一篇中,我們實作了基于算術平均的限幅濾波器。該濾波器對一定頻率以上的周期性幹擾和随機性的噪聲幹擾均有較好的效果。通過修改丢棄的極大值和極小值的數量可以應對在不同環境下的濾波要求。也可以對超長周期的幹擾和其它原因造成的劇變資料擁有較好的抑制作用。

  對于限幅的取值一般隻能根據采集系統的特點或者工程師的經驗來判斷,但并非是盲目的,因為很多情況下我們是能夠判斷出幹擾信号的大緻判斷範圍的。是以限幅值的選取,以及剔除的極大極小值的數量都需要根據集體的應用場景來設定。

  此外參考值的選取也會對濾波效果有決定性影響。一般根據具體的應用場景我們可以選取上一個測量結果、一定數量的之前的測量結果的算術平均或權重平均,或者采用累計的平均值等作為參考值。

歡迎關注:

濾波器開發之五:基于算術平均的限幅濾波器

如果閱讀這篇文章讓您略有所得,還請點選下方的【好文要頂】按鈕。

當然,如果您想及時了解我的部落格更新,不妨點選下方的【關注我】按鈕。

如果您希望更友善且及時的閱讀相關文章,也可以掃描上方二維碼關注我的微信公衆号【木南創智】

繼續閱讀