Python 十种数字滤波器

本文详细介绍了Python中十种数字滤波器的实现,包括限幅滤波、中位值滤波、算术平均滤波等,适用于噪声去除和信号平滑处理。通过对这些滤波方法的学习,可以提升在数据处理中的应用能力。
部署运行你感兴趣的模型镜像

参考: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")

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

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值