常见滤波算法(Python&C版本)

简介

受限于MCU自身的ADC外设缺陷,精度和稳定性通常较差,很多场景下需要用滤波算法进行补偿。滤波的主要目的是减少噪声与干扰对数据的影响,让数据更加接近真实值。

一阶低通滤波

一阶低通滤波是一种信号处理技术,用于去除信号中高频部分,保留低频部分。在滤波过程中,一阶低通滤波器会使得高于某个截止频率的信号被衰减,而低于截止频率的信号则会被保留。这有助于减少噪音或者不需要的信号成分,从而提高信号的质量。

**典型案例:**蓝牙耳机、音响

Python实现

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
# 生成示例数据
sensor_data = np.random.randn(200) # 正态分布随机数据
# 定义低通滤波函数
def low_pass_filter(data,cutoff_freq):
    filtered_data = np.copy(data)
    for i in range(1,len(data)):
        filtered_data[i] = (1-cutoff_freq)*filtered_data[i-1]+cutoff_freq*data[i]
    return filtered_data
# 设置截止频率
cutoff_freq = 0.2
# 应用低通滤波
filter_sensor_data = low_pass_filter(sensor_data,cutoff_freq)
# 绘制原始数据和滤波后数据
plt.figure(figsize=(10,6))
plt.plot(sensor_data)
plt.plot(filter_sensor_data)
plt.show()

C实现

均值滤波

**说明:**连续取N个采样值进行算术平均运算达到降噪目的;

N值较大时:信号平滑度较高,但灵敏度较低

N值较小时:信号平滑度较低,但灵敏度较高

**优点:**试用于对一般具有随机干扰的信号进行滤波。这种信号的特点是有一个平均值,信号在某一数值范围附近上下波动。

**缺点:**测量速度较慢或要求数据计算较快的实时控制不适用。

**典型案例:**电子秤...

Python实现

python 复制代码
import numpy as np
import matplotlib.pyplot as plt 
# 生成模拟示例数据
sensor_data = np.random.randn(200) # 正态分布随机数据
m = 0 # 起始角标
n = 11 # 在多少个数中取中间值,必须为奇数
def average_filter(data):
    global m,n
    data = sensor_data[m:m+n]
    m +=n
    value = np.average(data)
    return value

filter_sensor_data = np.zeros_like(sensor_data)

for i in range(0, len(sensor_data),n):
    filter_sensor_data[i] = average_filter(sensor_data)
    
# 绘制原始数据和滤波后数据
plt.figure(figsize=(10,6))
plt.plot(sensor_data,c="green")
plt.plot(filter_sensor_data,c="red")
plt.show()

C实现

滑动平均滤波

**说明:**把连续取N个采样值看成一个队列,队列的长度固定为N。每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出原则)。把队列中的N个数据进行算术平均运算,就可获得新的滤波结果。

**N值的选取:**流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4

**优点:**对周期性干扰有良好的抑制作用,平滑度高;试用于高频振荡的系统

**缺点:**灵敏度低;对偶然出现的脉冲性干扰的抑制作用较差,不适于脉冲干扰较严重的场合比较浪费RAM(改进方法,减去的不是队首的值,而是上一次得到的平均值)

**典型应用:**汽车上剩余可行驶里程预估

Python实现

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

sensor_data = np.random.randn(200)
n = 11
filter_sensor_data = np.zeros_like(sensor_data)
for i in range(1,len(sensor_data)):
    if i<n:
        temp_data = sensor_data[0:i]
        value = np.average(temp_data)
        filter_sensor_data[i] = value
    else:
        temp_data = sensor_data[i-n:i]
        value = np.average(temp_data)
        filter_sensor_data[i] = value
plt.figure(figsize=(10,6))
plt.plot(sensor_data,c="green")
plt.plot(filter_sensor_data,c="red")
plt.show()

C实现

中值滤波

**说明:**连续采样N次(N取奇数)把N次采样值按大小排列取中间值为本次有效值

**优点:**能有效克服因偶然因素引起的波动干扰;对温度、液位等变化缓慢的被测参数有良好的滤波效果

**缺点:**对流量,速度等快速变化的参数不宜。

**典型应用:**电子秤....

Python实现

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
# 生成模拟数据
sensor_data = np.random.randn(200) # 正态分布随机数据

# 起始角标
m = 0
n = 11 # 在多少个数中取中间值,必须为奇数

# 定义中值滤波算法
def middle_filter(data):
    global m,n
    data = sensor_data[m:m+n]
    m += n
    data2 = sorted(data)
    # 取中间值
    middle_index = int(len(data2)/2)
    value = data2[middle_index]
    return value
filter_sensor_data = np.ones_like(sensor_data)
# 绘制原始数据和滤波后数据
for i in range(0,len(sensor_data),n):
    filter_sensor_data[i] = middle_filter(sensor_data)
plt.figure(figsize=(10,6))
plt.plot(sensor_data,c="blue")
plt.plot(filter_sensor_data,c="red")
plt.show()

C实现

卡尔曼滤波

**说明:**根据当前的仪器"测量值" 和上一刻的 "预测量" 和 "误差",计算得到当前的最优量,再预测下一刻的量。里面比较突出的是观点是:把误差纳入计算,而且分为预测误差和测量误差两种,通称为噪声。还有一个非常大的特点是:误差独立存在,始终不受测量数据的影响。

**优点:**巧妙的融合了观测数据与估计数据,对误差进行闭环管理,将误差限定在一定范围。适用性范围很广,时效性和效果都很优秀。

**缺点:**需要调参,参数的大小对滤波的效果影响较大。

**典型应用:**卫星轨迹预测、火箭发射、无人机与机器人运动控制....

Python实现

python 复制代码
class KalmanFilter:
    def __init__(self,q=0.001,r=0.001) -> None:
        self.q = q # 过程噪声协方差
        self.r = r # 测量噪声协方差
        self.p = 5 # 估计误差协方差
        self.k_gain = 0 #卡尔曼增益
        self.prev_data = 0 # 先前数据值
    def updata(self,measurement):
        # 预测
        self.p +=self.q
        # 计算卡尔曼增益
        self.k_gain = self.p/(self.p+self.r)
        # 更新估计值
        estimation = self.prev_data + self.k_gain*(measurement-self.prev_data)
        # 更新估计误差协方差
        self.p = (1-self.k_gain)* self.p
        # 更新先前数据值
        self.prev_data = estimation
        return estimation

# 测试
kf = KalmanFilter()
input_data = 5
filter_data = kf.updata(input_data)
print(f"滤波后:filter_data")

import numpy as np
import matplotlib.pyplot as plt
sensor_data = np.random.randn(200)
n = 11
filter_sensor_data = np.zeros_like(sensor_data)
for i in range(1,len(sensor_data)):
    src_data = sensor_data[i]
    filter_sensor_data[i] = kf.updata(src_data)
    
plt.figure(figsize=(10,6))
plt.plot(sensor_data,c="green")
plt.plot(filter_sensor_data,c="red")
plt.show()

C实现

相关推荐
IT学长编程9 分钟前
计算机毕业设计 基于k-means的校园美食推荐系统 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】
大数据·python·毕业设计·kmeans·课程设计·毕业论文·美食推荐系统
猫头虎14 分钟前
HAMi 2.7.0 发布:全面拓展异构芯片支持,优化GPU资源调度与智能管理
嵌入式硬件·算法·prompt·aigc·embedding·gpu算力·ai-native
漫漫不慢.17 分钟前
算法练习-二分查找
java·开发语言·算法
如竟没有火炬36 分钟前
LRU缓存——双向链表+哈希表
数据结构·python·算法·leetcode·链表·缓存
沐欣工作室_lvyiyi38 分钟前
基于单片机的智能家居窗帘控制系统设计(论文+源码)
单片机·嵌入式硬件·毕业设计·智能家居·智能窗帘
Greedy Alg39 分钟前
LeetCode 236. 二叉树的最近公共祖先
算法
嵌入式分享1 小时前
嵌入式分享#41:RK3576改UART波特率【精简版】
linux·嵌入式硬件·ubuntu·嵌入式
爱吃生蚝的于勒1 小时前
【Linux】零基础学会Linux之权限
linux·运维·服务器·数据结构·git·算法·github
咖啡续命又一天1 小时前
python 自动化采集 ChromeDriver 安装
开发语言·python·自动化
兮山与2 小时前
算法3.0
算法