我是靠谱客的博主 能干钢笔,最近开发中收集的这篇文章主要介绍Python 十种数字滤波器,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 制作数据
      • 1.限幅滤波法
      • 2.中位值滤波法
      • 3.算术平均滤波法
      • 4.递推平均滤波法(又称滑动平均滤波法)
      • 5.中位值平均滤波法(又称防脉冲干扰平均滤波法)
      • 6.限幅平均滤波法
      • 7.一阶滞后滤波法
      • 8.加权递推平均滤波法
      • 9.消抖滤波法
      • 10.限幅消抖滤波法

参考:https://www.geek-workshop.com/thread-7694-1-1.html

制作数据

#!/usr/bin/python3
# author: WxxMaster
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
np.random.seed(1)
# Data = [0.03*i + np.sin(0.02*math.pi*i) + j for i, j in enumerate(np.random.rand((200)))]
Data = [0.03*i + np.sin(0.02*math.pi*i) + j for i, j in enumerate(np.random.normal(1, 0.5, (200)))]
plt.subplot(221)
plt.title("原数据")
plt.plot([i for i in range(200)], [0.03*i + np.sin(0.02*math.pi*i) for i in range(200)], color="g")
plt.subplot(222)
plt.title("噪音数据")
plt.plot([i for i in range(200)], Data, color="b")

1.限幅滤波法

def LimitFilter(Data, Amplitude):
'''
A、名称:限幅滤波法(又称程序判断滤波法)
B、方法:
根据经验判断,确定两次采样允许的最大偏差值(设为A),
每次检测到新值时判断:
如果本次值与上次值之差<=A,则本次值有效,
如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值。
C、优点:
能有效克服因偶然因素引起的脉冲干扰。
D、缺点:
无法抑制那种周期性的干扰。
'''
ReturnData = [Data[0]]
for Value in Data[1:]:
# print(abs(Value - ReturnData[-1]))
if abs(Value - ReturnData[-1]) < Amplitude:
# 限幅
ReturnData.append(Value)
else:
ReturnData.append(ReturnData[-1])
return ReturnData
NextData = LimitFilter(Data, 1)
plt.subplot(223)
plt.title("限幅滤波 A=1.0")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = LimitFilter(Data, 0.8)
plt.subplot(224)
plt.title("限幅滤波 A=0.8")
plt.plot([i for i in range(200)], NextData, color="y")

2.中位值滤波法

def MedianFilter(Data, N):
'''
A、名称:中位值滤波法
B、方法:
连续采样N次(N取奇数),把N次采样值按大小排列,
取中间值为本次有效值。
C、优点:
能有效克服因偶然因素引起的波动干扰;
对温度、液位的变化缓慢的被测参数有良好的滤波效果。
D、缺点:
对流量、速度等快速变化的参数不宜。
'''
ReturnData = []
StageList = []
for index, Value in enumerate(Data):
StageList.append(Value)
if (index+1) % N == 0:
StageList.sort() # 排序
# 取中值
if N%2 != 0:
ReturnData += [StageList[int((N+1) / 2) - 1]] * N
StageList.clear()
else:
ReturnData += [(StageList[int(N/2) - 1] + StageList[int(N/2)]) / 2] * N
StageList.clear()
# 处理剩余的数据
Residue = len(StageList)
if Residue != 0:
StageList.sort()
if Residue%2 != 0:
ReturnData += [StageList[(Residue+1)/2 - 1]] * Residue
else:
ReturnData += [(StageList[int(Residue/2) - 1] + StageList[int(Residue/2)]) / 2] * Residue
return ReturnData
NextData = MedianFilter(Data, 3)
plt.subplot(223)
plt.title("中值滤波 N=3")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = MedianFilter(Data, 6)
plt.subplot(224)
plt.title("中值滤波 N=6")
plt.plot([i for i in range(200)], NextData, color="y")

3.算术平均滤波法

def ArithmeticAverageFilter(Data, N):
'''
A、名称:算术平均滤波法
B、方法:
连续取N个采样值进行算术平均运算:
N值较大时:信号平滑度较高,但灵敏度较低;
N值较小时:信号平滑度较低,但灵敏度较高;
N值的选取:一般流量,N=12;压力:N=4。
C、优点:
适用于对一般具有随机干扰的信号进行滤波;
这种信号的特点是有一个平均值,信号在某一数值范围附近上下波动。
D、缺点:
对于测量速度较慢或要求数据计算速度较快的实时控制不适用;
比较浪费RAM。
'''
ReturnData = []
Accumulate = 0 # 和值
for index, Value in enumerate(Data):
Accumulate += Value
if (index+1) % N == 0:
Median = Accumulate / N
ReturnData += [Median] * N
Accumulate = 0
# 处理剩余的数据
if len(Data) % N != 0:
Median = Accumulate / (len(Data) % N)
ReturnData += [Median] * (len(Data) % N)
return ReturnData
NextData = ArithmeticAverageFilter(Data, 3)
plt.subplot(223)
plt.title("算术平均滤波 N=3")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = ArithmeticAverageFilter(Data, 6)
plt.subplot(224)
plt.title("算术平均滤波 N=6")
plt.plot([i for i in range(200)], NextData, color="y")

4.递推平均滤波法(又称滑动平均滤波法)

def RecursiveAverageFilter(Data, N):
'''
A、名称:递推平均滤波法(又称滑动平均滤波法)
B、方法:
把连续取得的N个采样值看成一个队列,队列的长度固定为N,
每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出原则),
把队列中的N个数据进行算术平均运算,获得新的滤波结果。
N值的选取:流量,N=12;压力,N=4;液面,N=4-12;温度,N=1-4。
C、优点:
对周期性干扰有良好的抑制作用,平滑度高;
适用于高频振荡的系统。
D、缺点:
灵敏度低,对偶然出现的脉冲性干扰的抑制作用较差;
不易消除由于脉冲干扰所引起的采样值偏差;
不适用于脉冲干扰比较严重的场合;
比较浪费RAM
'''
ReturnData = []
StageList = []
for Value in Data:
StageList.append(Value) # 入队
if len(StageList) > N:
StageList.pop(0)
# 出队
Number = len(StageList)
ReturnData.append(sum(StageList) / Number)
return ReturnData
NextData = RecursiveAverageFilter(Data, 3)
plt.subplot(223)
plt.title("递推平均滤波 N=3")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = RecursiveAverageFilter(Data, 6)
plt.subplot(224)
plt.title("递推平均滤波 N=6")
plt.plot([i for i in range(200)], NextData, color="y")

5.中位值平均滤波法(又称防脉冲干扰平均滤波法)

def MeanMedianValuesFilter(Data, N):
'''
A、名称:中位值平均滤波法(又称防脉冲干扰平均滤波法)
B、方法:
采一组队列去掉最大值和最小值后取平均值,
相当于“中位值滤波法”+“算术平均滤波法”。
连续采样N个数据,去掉一个最大值和一个最小值,
然后计算N-2个数据的算术平均值。
N值的选取:3-14。
C、优点:
融合了“中位值滤波法”+“算术平均滤波法”两种滤波法的优点。
对于偶然出现的脉冲性干扰,可消除由其所引起的采样值偏差。
对周期干扰有良好的抑制作用。
平滑度高,适于高频振荡的系统。
D、缺点:
计算速度较慢,和算术平均滤波法一样。
比较浪费RAM。
'''
ReturnData = []
StageList = []
for index, Value in enumerate(Data):
StageList.append(Value)
if (index+1) % N == 0:
StageList.sort() # 排序
StageList.pop();StageList.pop(0) # 删除最大值与最小值
ReturnData += [sum(StageList) / len(StageList)] * N
StageList.clear() # 清空列表
# 剩余数据处理
if len(StageList) != 0:
if len(StageList) == 1: # 剩余一个的处理
ReturnData.append(StageList[0])
elif len(StageList) == 2: # 剩余两个的处理
ReturnData += [(StageList[0] + StageList[1]) / 2] * 2
else:
# 剩余两个以上的处理
Residue = len(StageList)
StageList.sort()
StageList.pop();StageList.pop(0)
ReturnData += [sum(StageList) / len(StageList)] * Residue
return ReturnData
NextData = MeanMedianValuesFilter(Data, 4)
plt.subplot(223)
plt.title("中位值平均滤波 N=4")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = MeanMedianValuesFilter(Data, 8)
plt.subplot(224)
plt.title("中位值平均滤波 N=8")
plt.plot([i for i in range(200)], NextData, color="y")

6.限幅平均滤波法

def LimitingAverageFilter(Data, Amplitude, N):
'''
A、名称:限幅平均滤波法
B、方法:
相当于“限幅滤波法”+“递推平均滤波法”;
每次采样到的新数据先进行限幅处理,
再送入队列进行递推平均滤波处理。
C、优点:
融合了两种滤波法的优点;
对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差。
D、缺点:
比较浪费RAM。
'''
ReturnData = [Data[0]]
StageList = [Data[0]]
for Value in Data[1:]:
# 限幅处理
if abs(Value - StageList[-1]) < Amplitude:
StageList.append(Value)
else:
StageList.append(StageList[-1])
# 保持队列数量不超过N
if len(StageList) > N:
StageList.pop(0)
Number = len(StageList)
ReturnData.append(sum(StageList) / Number)
return ReturnData
NextData = LimitingAverageFilter(Data, 1, 3)
plt.subplot(223)
plt.title("限幅平均滤波 A=1 N=3")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = LimitingAverageFilter(Data, 1, 6)
plt.subplot(224)
plt.title("限幅平均滤波 A=1 N=6")
plt.plot([i for i in range(200)], NextData, color="y")

7.一阶滞后滤波法

def FirstOrderLagFilter(Data, A):
'''
A、名称:一阶滞后滤波法
B、方法:
取a=0-1,本次滤波结果=(1-a)*本次采样值+a*上次滤波结果。
C、优点:
对周期性干扰具有良好的抑制作用;
适用于波动频率较高的场合。
D、缺点:
相位滞后,灵敏度低;
滞后程度取决于a值大小;
不能消除滤波频率高于采样频率1/2的干扰信号。
'''
ReturnData = [Data[0]]
for Value in Data[1:]:
ReturnValue = (1-A) * Value + A*ReturnData[-1]
ReturnData.append(ReturnValue)
return ReturnData
NextData = FirstOrderLagFilter(Data, 0.8)
plt.subplot(223)
plt.title("一阶滞后滤波 A=0.8")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = FirstOrderLagFilter(Data, 0.6)
plt.subplot(224)
plt.title("一阶滞后滤波 A=0.6")
plt.plot([i for i in range(200)], NextData, color="y")

8.加权递推平均滤波法

def WeightedRecursiveAveragingFalter(Data, N, Weight = None):
'''
A、名称:加权递推平均滤波法
B、方法:
是对递推平均滤波法的改进,即不同时刻的数据加以不同的权;
通常是,越接近现时刻的数据,权取得越大。
给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低。
C、优点:
适用于有较大纯滞后时间常数的对象,和采样周期较短的系统。
D、缺点:
对于纯滞后时间常数较小、采样周期较长、变化缓慢的信号;
不能迅速反应系统当前所受干扰的严重程度,滤波效果差。
'''
if Weight == None:
Weight = [i for i in range(1, N+1)] # [1, 2, 3, 4, 5······]
WeightSum = sum(Weight)
Weight = [i/WeightSum for i in Weight] # 归一化
ReturnData = []
StageList = []
for Value in Data:
# 入队与出队
StageList.append(Value)
if len(StageList) > N:
StageList.pop(0)
if len(StageList) < N:
WNum = 0
VNum = 0
for W, V in zip(Weight[-len(StageList):], StageList):
WNum += W
VNum += V
ReturnData.append(VNum/WNum)
else:
SRList = [W*V for W, V in zip(Weight, StageList)]
ReturnData.append(sum(SRList))
return ReturnData
NextData = WeightedRecursiveAveragingFalter(Data, 3)
plt.subplot(223)
plt.title("加权递推平均滤波 N=3")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = WeightedRecursiveAveragingFalter(Data, 6)
plt.subplot(224)
plt.title("加权递推平均滤波 N=6")
plt.plot([i for i in range(200)], NextData, color="y")

9.消抖滤波法

def DisappearsShakesFilter(Data, A):
'''
A、名称:消抖滤波法
B、方法:
设置一个滤波计数器,将每次采样值与当前有效值比较:
如果采样值=当前有效值,则计数器清零;
如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出);
如果计数器溢出,则将本次值替换当前有效值,并清计数器。
C、优点:
对于变化缓慢的被测参数有较好的滤波效果;
可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动。
D、缺点:
对于快速变化的参数不宜;
如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统。
'''
ReturnData = [Data[0]]
ValidValue = Data[0]
# 有效值
Counter = 0
# 计数器
for Value in Data[1:]:
if Value == ValidValue:
Counter = 0
else:
Counter += 1
if Counter > A: # 计数器大于阀值
ValidValue = Value
Counter = 0
ReturnData.append(ValidValue)
return ReturnData
NextData = DisappearsShakesFilter(Data, 2)
plt.subplot(223)
plt.title("消抖滤波 A=2")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = DisappearsShakesFilter(Data, 4)
plt.subplot(224)
plt.title("消抖滤波 A=4")
plt.plot([i for i in range(200)], NextData, color="y")

10.限幅消抖滤波法

def Limit_DisappearsShakesFilter(Data, a, A):
'''
A、名称:限幅消抖滤波法
B、方法:
相当于“限幅滤波法”+“消抖滤波法”;
先限幅,后消抖。
C、优点:
继承了“限幅”和“消抖”的优点;
改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统。
D、缺点:
对于快速变化的参数不宜。
'''
ReturnData = [Data[0]]
ValidValue = Data[0]
Counter = 0
for Value in Data[1:]:
# 限幅处理
if abs(Value - ReturnData[-1]) > a:
Value = ReturnData[-1]
if Value == ValidValue:
Counter = 0
else:
Counter += 1
if Counter > A:
ValidValue = Value
Counter = 0
ReturnData.append(ValidValue)
return ReturnData
NextData = Limit_DisappearsShakesFilter(Data, 0.8, 2)
plt.subplot(223)
plt.title("限幅消抖滤波 a=0.8 A=2")
plt.plot([i for i in range(200)], NextData, color="r")
NextData = Limit_DisappearsShakesFilter(Data, 0.6, 2)
plt.subplot(224)
plt.title("限幅消抖滤波 a=0.6 A=2")
plt.plot([i for i in range(200)], NextData, color="y")

学习过程中,若发现有错误之处请指出,谢谢!

最后

以上就是能干钢笔为你收集整理的Python 十种数字滤波器的全部内容,希望文章能够帮你解决Python 十种数字滤波器所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部