《An Introduction to Signal Smoothing》譯文

最近在作數據平滑相關的工做,正好讀到該篇博客,感受不錯,就翻譯了一下。原連接:An Introduction to Signal Smoothingmarkdown

信號平滑簡介

噪聲無處不在,不論是在採集手機遊戲的加速度數據仍是在測量房間的溫度,都會引入偏差。即便咱們有能力消除全部的偏差,測量的結果依舊包含必定程度的不肯定性。假如玩家隨意點擊了一下手機屏幕,他們到底想點擊哪裏是不肯定的。全部這些問題都強迫咱們從新思考數據的採集和預處理。函數

1. 簡介

濾波器是尋找產生觀測數據最可能信號的數學工具。它能夠對滲透進傳感器的噪聲和不肯定性進行消除。當前的各類設備,如觸屏、遊戲手柄、手機和遊戲控制器等都是經過傳感器採集用戶的輸入,因此這些設備都不可避免地會引入噪聲。因此濾波器在用戶體驗上扮演着很是重要的角色。
本博客會介紹關於平滑濾波器的基本知識。將這些知識應用到遊戲中會極大提高遊戲體驗。工具

2. 噪聲信號

用一個簡單例子來解釋噪聲是如何幹擾信號的。假設一個傳感器每隔固定時間採樣一下數據,在時刻i產生觀測值 Si 。若是你是遊戲開發者,這個傳感器極可能是一個控制器,獲得的數據可能爲:Input.GetAxis("Vertical")。若是你是一個電子工程師,這個傳感器多是電位計,用來測量電壓: analogRead(3)。這些時間序列都有一個共同點:都被噪聲干擾。下圖展現了一個被噪聲污染的信號:

在這個例子中,噪聲被人工添加到原始信號中。針對原始信號的每個點 Si 加上一個隨機值:
ui

ni=Si+rand()

若是知足上面的條件,咱們就說噪聲是知足可加性的,而且是均勻分佈的。這時添加的噪聲就獨立於原始信號。知足可加性的一致性噪聲一般來源於固定的外部干擾。

3. 滑動平均(Moving Average)

是否能重構被噪聲污染的信號呢?答案是:看狀況。這依賴於噪聲的類型和幅度。減弱噪聲的最簡單方法被稱爲滑動平均。該方法基於這樣一個假設:獨立的噪聲不會改變信號的基本結構。若是假設成立,則求幾個連續點的平均值就能夠減弱噪聲。正如其名字所表示的,滑動平均就是求給定點和其鄰居的平均值做爲信號值。例如,咱們對三個點求平均值,則過濾以後的信號爲:
atom

Fi=Ni1+Ni+Ni+13

當得到全部的觀測值以後,咱們能夠定義窗口大小爲N=2K+1的滑動平均爲:
Fi=1Nj=k+kSij

在下圖中,用窗口大小爲6的滑動平均對上圖的信號進行處理:

能夠看出,原始信號幾乎被完整地恢復出來。若是你是開發者,能夠用下面的代碼實現上述過濾:

public float [] MovingAverage (float [] data, int size)
{
    float [] filter = new float [data.length];
    for (int i = points/2; i < data.length-points/2; i++)
    {
        float mean = 0;
        for (var j = -points/2; j < points/2; j++)
            mean += data[i + j];

        filter[i] = mean / size;
    }
    return filter;
}

增長窗長能夠進一步減弱噪聲的影響,但同時也會使原始信號過分平滑。滑動平均特別適合於連續和平穩的信號。若是信號變化較爲劇烈,滑動平都可能會使原始信號的變化大於噪聲的消除(也即功不抵過)。

上圖中,雖然滑動平均減少了信號的變化程度,可是完美地重構了信號的線性部分。當咱們在處理包含可加性噪聲的線性信號時,滑動平均是最好的選擇。固然,上面的例子也過於理想化,在實際中很難出現。spa

4. 中心化的滑動平均

上面介紹的滑動平均有個限制:窗口長度N必須爲奇數。這樣計算的平均值就知足對稱性。假如窗口長度N=2k爲偶數,此時咱們有兩種平滑方法(假定k=2):
翻譯

MAL4=Ni2+Ni1+Ni+Ni+14

MAR4=Ni1+Ni+Ni+1+Ni+24

上述兩個公式都是合法的,沒有特別的偏向性。因此咱們能夠對這兩個公式求平均值,得到一箇中心化的滑動平均,這一般被稱爲2×4MA。
2×4MA=12[14(Ni2+Ni1+Ni+Ni+1)+14(Ni1+Ni+Ni+1+Ni+2)]

=Ni28+Ni14+Ni4+Ni+14+Ni+28

上面的結果特別像以 Ni 爲中心的滑動平均,可是和前面介紹的滑動平均仍是不一樣的。

5. 加權滑動平均

滑動平均中每一個點的權重是相同的,一個更加合理的選擇是對靠近 Si 的點賦予更大的權重,這就是加權滑動平均:
code

Fi=j=k+kSijWk+j

Wj 的和必須等於1。
針對加權滑動平均,能夠對前面的滑動平均代碼進行下面的修改:

for (var j = -points/2; j < points/2; j++)
            mean += data[i + j] * weights[j+points/2];

回過頭來重看中心化的滑動平均,咱們就能夠說2×4MA其實就是權重爲1/8,1/4,1/4,1/4,1/8的加權滑動平均。
加權的方法難以想象得有效,可是引入了更多的參數。若是你對泛函分析很瞭解,可能很容易將上面的操做聯想到卷積操做符上。經過仔細地挑選權重能夠帶來不少有趣的性質,例如實現邊緣檢測或者高斯模糊等。
舉一個邊緣檢測的例子,咱們對一個方波執行墨西哥帽小波的卷積操做,須要作的就是將權重設置爲下述函數上的點:
遊戲

f(t)=(1t2)et22

而後代碼修改爲:

float[] kernel = new float[10];
for (int i = 0; i <= kernel.length; t ++)
{
    float t = i +4;
    kernel[i] = (1-(t*t)) * Math.exp(-(t*t)/2);
}

上述卷積函數能夠用來進行邊緣檢測。若是你是一個遊戲開發者,上述方法能夠用來檢測玩家的忽然移動,這一般是運動檢測的第一步。
ip

6. 結論

本博客介紹了信號中的噪聲問題以及兩種解決方法。須要記住一點,沒有一種方法是完美的,每一個方法都有其優缺點,咱們須要知道它們的適用範圍。

相關文章
相關標籤/搜索