简单易学的几大经典滤波算法(含代码及仿真)

一、限幅滤波法
设定两次采样允许的最大偏差为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()

一阶滞后滤波

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