簡單易學的幾大經典濾波算法(含代碼及仿真)

一、限幅濾波法
設定兩次採樣允許的最大偏差爲A
如果(本次值-上次值)的絕對值大於A,則本次值無效,用上次值代替本次值
如果(本次值-上次值)的絕對值大於A,則本次值有效,採用本次值

import numpy as np          
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號

plt.figure(figsize = (20,8))
list_s = []

s = np.random.normal(0,25,400)
plt.plot(s,label = '原始數據')

for i in range(len(s)-1):  
    if abs(s[i+1] - s[i]) >= 15:
        s[i+1] = s[i]
    list_s.append(s[i+1])
        
plt.plot(list_s,label = '濾波後數據')
plt.title('限幅濾波法')
plt.legend()
plt.show()

限幅濾波

二、中位值濾波法
連續採樣N次,N取奇數
把N次值按從小到大或從大到小順序排列,取中位數爲本次有效結果

plt.figure(figsize = (20,8))

s = np.random.normal(0,25,400)
plt.plot(s,label = '原始數據')

n = 7     #一次採樣的次數
rank = []
for i in range(int(len(s)/n)):
    select_s = s[i*n:(i+1)*n]     #切片選取一次採樣的個數
    mid_s = np.median(select_s)
    for j in range(n):       #將取到的值都賦值爲中值,方便畫圖體現,實際中可以只要一次值
        rank.append(mid_s)

plt.plot(rank,label = '濾波後的數據')
plt.title('中值濾波算法')
plt.legend()
plt.show()

中值濾波

三、算數平均濾波法
連續取樣N次做算數平均運算,得到的平均數爲本次採樣結果
N值較大:平滑度越高,但靈敏度較低
N值較小:平滑度越低,但靈敏度高

plt.figure(figsize = (20,8))

s = np.random.normal(0,25,400)
plt.plot(s,label = '原始數據')
mean = []
n = 7     #一次採樣的次數
for i in range(int(len(s)/n)):
    select_s = s[i*n:(i+1)*n]     #切片選取一次採樣的個數
    mean_s = np.mean(select_s)
    for j in range(n):       #將取到的值都賦值爲平均值,方便畫圖體現,實際中可以只要一次值
        mean.append(mean_s)

plt.plot(mean,label = '濾波後的數據')
plt.title('算數平均濾波算法')
plt.legend()
plt.show()

算數平均濾波

四、遞推平均濾波法
把連續取N個採樣值看成一個隊列,遵循先進先出原則
隊列長度固定爲N
每次採樣到一個新數據放入隊尾,並去除隊首的數據
把隊列中的數據進行算數平均,即爲本次結果

plt.figure(figsize = (20,8))

s = np.random.normal(0,25,400)
plt.plot(s,label = '原始數據')

N = 7      #隊列大小
mean_list = []
select_s = list(s[i:i+N])      #先選擇一個隊列的數據,求平均
mean = np.mean(select_s)
select_s.insert(len(select_s),select_s[0])    #左移一位
select_s.remove(select_s[0])
#select_s[-1] = mean
mean_list.append(mean)

for i in range(len(s)-N):       #然後添加一個新數據,左移一位,去頭去尾,重複迭代
    select_s.append(s[i+N])
    select_s.insert(len(select_s),select_s[0])    #左移一位
    select_s.remove(select_s[0])
    select_s.remove(select_s[-1])
    mean = np.mean(select_s)
    #select_s[-1] = mean
    mean_list.append(mean)

plt.plot(mean_list,label = '濾波後的數據')
plt.title('滑動平均濾波算法')
plt.legend()
plt.show()

滑動平均濾波

五、中位值平均濾波法
相當於 中位值濾波算法+算數平均濾波算法
連續採樣N個數據,按順序排列
去頭去尾,進行平均

plt.figure(figsize = (20,8))

s = np.random.normal(0,25,400)
plt.plot(s,label = '原始數據')
mean = []
n = 7     #一次採樣的次數
for i in range(int(len(s)/n)):
    select_s = s[i*n:(i+1)*n]     #切片選取一次採樣的個數
    select_s = sorted(select_s)
    select_s.remove(select_s[0])
    select_s.remove(select_s[-1])

    mean_s = np.mean(select_s)
    for j in range(n):       #將取到的值都賦值爲平均值,方便畫圖體現,實際中可以只要一次值
        mean.append(mean_s)

plt.plot(mean,label = '濾波後的數據')
plt.title('中位值平均濾波算法')
plt.legend()
plt.show()

中位值平均濾波

六、限幅平均濾波法
相當於 限幅濾波算法+遞推平均濾波算法
每次採樣到新數據前先進行限幅處理
再送入隊列進行遞推平均濾波
(此處稍微做了改動,代碼中將每次得到的平均值送入隊尾,這樣得到的濾波數據更偏向於穩定)

plt.figure(figsize = (20,8))

s = np.random.normal(0,25,400)
plt.plot(s,label = '原始數據')

N = 8      #隊列大小
mean_list = []
select_s = list(s[i:i+N])      #先選擇一個隊列的數據,求平均
mean = np.mean(select_s)
select_s.insert(len(select_s),select_s[0])    #左移一位
select_s.remove(select_s[0])
select_s[-1] = mean
mean_list.append(mean)

for i in range(len(s)-N):       #然後添加一個新數據,左移一位,去頭去尾,重複迭代
    if abs(select_s[-1] - s[i+N]) >= 30:
        s[i+N] = select_s[-1]
    else:
        s[i+N] = s[i+N]
        
    select_s.append(s[i+N])
    select_s.insert(len(select_s),select_s[0])    #左移一位
    select_s.remove(select_s[0])
    select_s.remove(select_s[-1])
    mean = np.mean(select_s)
    select_s[-1] = mean
    mean_list.append(mean)

plt.plot(mean_list,label = '濾波後的數據')
plt.title('限幅平均濾波算法')
plt.legend()
plt.show()

限幅平均濾波

七、一階滯後濾波法
取a = 0~1
本次濾波結果 = (1-a)* 本次值 + a * 上次值

plt.figure(figsize = (20,8))
list_s = []

s = np.random.normal(0,25,400)
plt.plot(s,label = '原始數據')
a = 0.7    #a取0-1之間,a越接近1越穩定,越接近0越靈敏

for i in range(len(s)-1): 
    s[i+1] = (1-a) * s[i+1] + a * s[i]
    list_s.append(s[i+1])
        
plt.plot(list_s,label = '濾波後數據')
plt.title('一階滯後濾波算法')
plt.legend()
plt.show()

一階滯後濾波

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章