簡體   English   中英

降低信號數據噪聲的算法?

[英]Algorithm for reducing noise from signal data?

我正在嘗試編寫一個程序來平滑一些傳感器數據。

傳感器提供0到100的閾值輸入。它通常精確到2個單位左右,但讀數是跳躍的。

我每秒輸入很多次,並希望從這些數據中創建動態平均值,而不是那么跳躍。

如何以一種可以獲得平滑移動數字,更准確數字(與讀數實時保持在一起)顯示在界面上的方式來平均最近的輸入?

謝謝你的幫助。

根據您的數據,您可以通過計算平均值來平衡測量值。

  • 使用一定數量的先前結果

     int values[BUFLEN]; value = // your new raw measured value index = index++ % BUFLEN; values[index] = value; avg = 0; for(int i=0; i<BUFLEN; i++) { avg = avg + values[i] / BUFLEN; // evenly weighted } 

    如果你願意,也可以使用不均勻的重量。 此外,如果您使用相同的權重,則可以優化此循環。

  • 使用浮動平均值

     avg = (avg * 0.9) + (value * 0.1) // slow response avg = (avg * 0.5) + (value * 0.5) // fast response float q = // new ratio avg = (avg * (1.0 - q)) + (value * q) // general solution 

浮動平均值(數學上)是所有元素的加權和,其中權重是q Ni ,其中N是總測量值, i是元素的運行索引。 所有元素都涉及平均值,而不僅僅是有限數量的元素。

您可以檢查錯誤措施的頻率,與平均值的距離是什么,您希望您的(計算的)措施遵循實際流程的響應等等。

此外,如果你有離散值(整數),你必須小心使用舍入的東西。 我建議以浮點進行所有計算,然后將結果舍入到最接近的整數。 但是將計算的平均值存儲在下一輪的浮點數中。

更新:

為了反映您在同一時間保持最新准確的問題:

問題是我們不確定最新數據是顯示趨勢還是錯誤閱讀的結果。 我會告訴你一個例子:

SEQ1: 15 15 14 15 15 [10]  6  6  5  6  6 
SEQ2: 15 15 14 15 15 [10] 20 15 14 15 15

那么, [10]在每個序列中意味着什么:在第一個序列中,它代表一個嚴肅的運動,一個趨勢。 在第二個中,這只是一個誤讀。 但是當你剛讀完[10] ,你不知道下一個是什么。 所以,你必須延遲讀取的效果。 所以,它不會是最新的

同樣,您使用的是平均值,即計算值。 所以,它不准確

這是一種平衡的情況 值越新,准確性越低(誤讀的次數越多)。 數據越准確,延遲就越大。 根據數據系列,您必須明智地選擇它。

我使用第二種(浮動平均)算法為您計算了三種情景。 q的值設置為lazynormaleager

SEQ1:     15    15    14    15    15    10     6     6     5     6     6 
// q=0.25, "lazy"
Avg       15.00 15.00 14.75 14.81 14.86 13.64 11.73 10.30  8.98  8.23  7.67
Rounded   15    15    15    15    15    14    12    10     9     8     7   

// q=0.5, "normal"
Avg       15.00 15.00 14.50 14.75 14.88 12.44  9.22  7.61  6.30  6.15  6.08
Rounded   15    15    15    15    15    12     9     7     6     6     6

// q=0.75, "eager"
Avg       15.00 15.00 14.25 14.81 14.95 11.23  7.31  6.33  5.33  5.83  5.96
Rounded   15    15    14    15    15    11     7     6     5     5     6

您可以看到延遲計算在5次迭代后仍未達到6 ,可能還需要3次。

正常幾乎不容易出錯,(14.5只是四舍五入),但幾乎可以立即跟隨趨勢。

渴望熱切關注這些措施,只是略微緩解曲線。 它甚至無法檢測到15-14-15的錯誤讀數。

該系列的最佳值之上將約為0.4 - 0.45我想。 有必要使用實際測量數據的樣本來查看什么是參數值的行為。

實際上我最喜歡的是浮動平均算法,它易於實現並且給出了良好的結果(如果參數化良好)。

免責聲明:這將導致非常平滑的結果 - 即使在此期間價值上下波動,這可能只是顯示一條直線。 這將顯示平均隨時間的變化。 如果不希望這樣,這個答案可能不是你想要的。

假設我們對最后的k輸入值進行平均。

首先要注意的是:

Average at time i = (value[i] + value[i-1] + ... + value[i-k+1]) / k
                  = value[i]/k + value[i-1]/k + ... + value[i-k+1]/k

and

Average at time i-1 = value[i-1]/k + value[i-2]/k + ... + value[i-k+2]/k

thus, cancelling out common terms...

Average at time i = Average at time i-1 + value[i]/k - value[i-k+2]/k

並且,為了避免潛在的舍入問題,請將除以k除以 - 除非得到平均值(這樣做不會使數學無效)。

那么,對於算法:

  • 有一個大小為k的圓形數組。 將此數組中的所有值初始化為0。
  • 保持已填充元素數量的計數(初始化為0)。
  • 無論何時插入此緩沖區,請按如下方式更新平均值:
    average = newValue - overriddenValue
    如果它小於k則增加計數。
  • 獲取顯示平均值時,只需將其除以計數即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM