Python濾波

import numpy as np
import matplotlib.pyplot as plt

def limit_filter(data, top=4):
    '''
        限幅濾波法(又稱程序判斷濾波法)  
        A、方法:  根據經驗判斷,確定兩次採樣允許的最大偏差值(設爲top)每次檢測到新值時判斷:如果本次值與上次值之差<=top,則本次值有效  如果本次值與上次值之差>top,則本次值無效,放棄本次值,用上次值代替本次值  
        B、優點:  能有效克服因偶然因素引起的脈衝干擾  
        C、缺點:  無法抑制那種週期性的干擾  平滑度差
    '''
    flag_arr = np.argwhere(data<0)
    temp_data = abs(data)
    for i in range(1, len(temp_data)):
        if abs(temp_data[i] - temp_data[i-1])  > top:
            temp_data[i] = temp_data[i-1]
    temp_data[flag_arr] *= -1
    return temp_data

def median_filter(data, num=3):
    '''
        中位值濾波法  
        A、方法:  連續採樣num次(num取奇數)  把num次採樣值按大小排列  取中間值爲本次有效值  
        B、優點:  能有效克服因偶然因素引起的波動干擾  對溫度、液位的變化緩慢的被測參數有良好的濾波效果  
        C、缺點:  對流量、速度等快速變化的參數不宜  
    '''
    data_length = len(data)
    item_num = data_length // num + 1
    padwidth = item_num * num - data_length
    temp_data = np.pad(data, (0, padwidth), 'edge').reshape(item_num, num)
    median_arr = np.median(temp_data, axis=1).reshape(item_num).repeat(num)[:data_length]
    return median_arr


def average_filter(data, num=3):
    '''
        算術平均濾波法  
        A、方法:  連續取num個採樣值進行算術平均運算  num值較大時:信號平滑度較高,但靈敏度較低  num值較小時:信號平滑度較低,但靈敏度較高  num值的選取:一般流量,num=12;壓力:num=4  
        B、優點:  適用於對一般具有隨機干擾的信號進行濾波  這樣信號的特點是有一個平均值,信號在某一數值範圍附近上下波動  
        C、缺點:  對於測量速度較慢或要求數據計算速度較快的實時控制不適用  比較浪費RAM  
    '''
    data_length = len(data)
    item_num = data_length // num + 1
    padwidth = item_num * num - data_length
    temp_data = np.pad(data, (0, padwidth), 'edge').reshape(item_num, num)
    median_arr = np.mean(temp_data, axis=1).reshape(item_num).repeat(num)[:data_length]
    return median_arr

def dynamic_average_filter(data, num=3):
    '''
        遞推平均濾波法(又稱滑動平均濾波法)  
        A、方法:  把連續取num個採樣值看成一個隊列  隊列的長度固定爲num  每次採樣到一個新數據放入隊尾,並扔掉原來隊首的一次數據.(先進先出原則)  把隊列中的num個數據進行算術平均運算,就可獲得新的濾波結果  num值的選取:流量,num=12;壓力:num=4;液麪,num=4~12;溫度,num=1~4  
        B、優點:  對週期性干擾有良好的抑制作用,平滑度高  適用於高頻振盪的系統  
        C、缺點:  靈敏度低  對偶然出現的脈衝性干擾的抑制作用較差  不易消除由於脈衝干擾所引起的採樣值偏差  不適用於脈衝干擾比較嚴重的場合  比較浪費RAM  
    '''
    temp_data = data.copy()
    for i in range(len(temp_data)):
        temp_data[i] = np.mean(temp_data[i:i+num])
    return temp_data


def median_average_filter(data, num=3):
    '''
        中位值平均濾波法(又稱防脈衝干擾平均濾波法)  
        A、方法:  相當於“中位值濾波法”+“算術平均濾波法”  連續採樣num個數據,去掉一個最大值和一個最小值  然後計算num-2個數據的算術平均值  num值的選取:3~14  
        B、優點:  融合了兩種濾波法的優點  對於偶然出現的脈衝性干擾,可消除由於脈衝干擾所引起的採樣值偏差  
        C、缺點:  測量速度較慢,和算術平均濾波法一樣  比較浪費RAM  
    '''
    data_length = len(data)
    item_num = data_length // num + 1
    padwidth = item_num * num - data_length
    temp_data = np.pad(data, (0, padwidth), 'edge').reshape(item_num, num)
    temp_data = np.sort(temp_data, axis=1)[:, 1:-1]
    median_arr = np.mean(temp_data, axis=1).reshape(item_num).repeat(num)[:data_length]
    return median_arr

def dynamic_limit_average_filter(data, num=3, top=4):
    '''
        限幅平均濾波法  
        A、方法:  相當於“限幅濾波法”+“遞推平均濾波法”  每次採樣到的新數據先進行限幅處理,  再送入隊列進行遞推平均濾波處理  
        B、優點:  融合了兩種濾波法的優點  對於偶然出現的脈衝性干擾,可消除由於脈衝干擾所引起的採樣值偏差  
        C、缺點:  比較浪費RAM  
    '''
    flag_arr = np.argwhere(data<0)
    temp_data = abs(data)
    for i in range(1, len(temp_data)):
        if abs(temp_data[i] - temp_data[i-1])  > top:
            temp_data[i] = temp_data[i-1]
        temp_data[i] = np.mean(temp_data[i:i+num])

    temp_data[flag_arr] *= -1
    return temp_data


def lag_filter(data, rate=0.3):
    '''
        一階滯後濾波法  
        A、方法:  取a=0~1  本次濾波結果=(1-a)*本次採樣值+a*上次濾波結果  
        B、優點:  對週期性干擾具有良好的抑制作用  適用於波動頻率較高的場合  
        C、缺點:  相位滯後,靈敏度低  滯後程度取決於a值大小  不能消除濾波頻率高於採樣頻率的1/2的干擾信號  
    '''
    temp_data = data.copy()
    for i in range(1, len(temp_data)):
        temp_data[i] = (1-rate) * temp_data[i] + rate * temp_data[i-1]
    return temp_data

def dynamic_weight_average_filter(data, num):
    '''
        加權遞推平均濾波法  
        A、方法:  是對遞推平均濾波法的改進,即不同時刻的數據加以不同的權  通常是,越接近現時刻的數據,權取得越大。  給予新採樣值的權係數越大,則靈敏度越高,但信號平滑度越低  
        B、優點:  適用於有較大純滯後時間常數的對象  和採樣週期較短的系統  
        C、缺點:  對於純滯後時間常數較小,採樣週期較長,變化緩慢的信號  不能迅速反應系統當前所受干擾的嚴重程度,濾波效果差 
    '''
    pass

def test3():
    '''
        消抖濾波法  
        A、方法:  設置一個濾波計數器  將每次採樣值與當前有效值比較:  如果採樣值=當前有效值,則計數器清零  如果採樣值<>當前有效值,則計數器+1,並判斷計數器是否>=上限N(溢出)  如果計數器溢出,則將本次值替換當前有效值,並清計數器  
        B、優點:  對於變化緩慢的被測參數有較好的濾波效果,  可避免在臨界值附近控制器的反覆開/關跳動或顯示器上數值抖動  
        C、缺點:  對於快速變化的參數不宜  如果在計數器溢出的那一次採樣到的值恰好是干擾值,則會將干擾值當作有效值導  入系統 
    '''
    pass


def test4():
    '''
        限幅消抖濾波法  
        A、方法:  相當於“限幅濾波法”+“消抖濾波法”  先限幅,後消抖  
        B、優點:  繼承了“限幅”和“消抖”的優點  改進了“消抖濾波法”中的某些缺陷,避免將干擾值導入系統  
        C、缺點:  對於快速變化的參數不宜 
    '''
    pass




if __name__ == '__main__':
    a =  np.sin(np.linspace(1, 50, 200)*np.pi) * 2
    Q = np.random.rand(200)
    Q[12] = 5
    Q[66] = 5
    Q[77] = -5
    Q[78] = -4
    Q[79] = -5
    a = a + Q
    T = np.array(range(len(a)))
    from scipy.interpolate import spline
    xnew = np.linspace(T.min(),T.max(),len(a)*3) #300 represents number of points to make between T.min and T.max
    power_smooth = spline(T,a,xnew)

    plt.plot(xnew, power_smooth)
    plt.ylim(-5,5)
    # 中位值濾波
    # median_data = median_filter(a, 3)
    # plt.title("media:3")
    # plt.plot(median_data)

    # 算術平均值濾波
    # average_data = average_filter(a, 3)
    # plt.title("average:3")
    # plt.plot(average_data)

    # 滑動平均值濾波
    # dynamic_average_data = dynamic_average_filter(a, 3)
    # plt.title("dynamic_average:3")
    # plt.plot(dynamic_average_data)

    # 限幅平均濾波
    # dynamic_limit_average_data = dynamic_limit_average_filter(a, 3, 4)
    # plt.title("limit:4 average:3")
    # plt.plot(dynamic_limit_average_data)

    # # 中位值平均濾波
    median_average_data = median_average_filter(a, 3)
    plt.title("median_average:3")
    plt.plot(median_average_data)

    # 限幅濾波
    # limited_data = limit_filter(a, 4)
    # plt.title("limit:4")
    # plt.plot(limited_data)

    # 一階滯後濾波
    # lag_data = lag_filter(a, 0.3)
    # plt.title("lag:0.3")
    # plt.plot(lag_data)


    plt.show()

 

發佈了61 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章