信号处理学习笔记1:软件RC一阶高通\低通滤波

今日学习一下 一阶惯性数字低通滤波 一阶惯性数字高通滤波

目录

[为什么叫 "一阶":](#为什么叫 “一阶”:)

适用场景与优势:

初值毛刺的影响与解决:

测试代码贴出:

C语言:

C运行结果:

数据绘图展示(Python):

绘图结果:


为什么叫 "一阶":

因为公式里只用到上一时刻的值,没有更复杂的历史数据。

低通:只依赖 上一次输出

高通:只依赖 上一次输出 + 上一次输入

没有二阶、三阶那种多阶记忆,所以叫 一阶

适用场景与优势:

一阶滤波适用场景:

一阶数字滤波适用于温度、湿度、压力、直流电压、液位变化缓慢、易受高频噪声干扰的物理量采集场景。低通滤波可有效去除采样噪声,使数据平滑稳定;高通滤波可去除信号基线漂移,提取动态变化量。

低通 = 显示当前值(平滑后)

高通 = 只显示变化幅度(变了多少)
优势:

算法简单,计算量小,适合单片机等嵌入式平台实时运行。

稳定性高,不易受数据异常影响(除初始值外)。

对于慢变物理量,一阶滤波即可满足降噪与平滑需求。

实时性好,无明显信号延迟。

初值毛刺的影响与解决:

如果第一个值就是毛刺(极大 / 极小)

低通是:起点错了 → 慢慢修正 前面一大段数据全废

那么低通滤波会从这个错误值开始,慢慢往正确值靠近过程会很慢、很歪,

前面一大段数 据全废。

高通是:起点错了 → 整条路都歪了! 波形基线整体偏移 整条波形报废

高通输出会整体往上飘 / 往下沉,再也回不到 0 基线!

高通滤波会认为:"整个信号的基准就是 100,不是 0"

于是它把所有数据都减去 100最终整条波形整体下沉 / 偏移 基线永远歪了!
解决办法:

方法 1:跳过前 N 个数据(最简单,实验最常用)

方法 2:初始值不用第一个数据,用手动设定值

方法 3:先采样多次求平均,再开始滤波(最稳)用平均值当起点,毛刺就被平均掉了。

测试代码贴出:

C语言:

cpp 复制代码
 #include <stdio.h>


// 滤波参数(alpha 越小,滤波越强)
#define ALPHA 0.05f

/*
    1. 一阶低通滤波(去噪、平滑)
    输入:当前原始数据,上一次滤波结果
    输出:本次滤波后数据

    新值 = 一小部分当前值 + 一大部分上一次的值
    新值 = 0.05 * 当前采样 + 0.95 * 上一次结果
    只相信当前数据 5%,95% 相信过去的稳定值
    低通滤波的目的:去掉噪声,保留趋势
    噪声 = 快速跳变(要去掉)
    真实信号 = 缓慢变化(要保留)
    低通滤波确实会改变数据 作用就是抑制突变、减小剧烈变化
    让数据从 "乱跳" 变成 "平稳顺滑"
*/
float low_pass_filter(float current_data, float last_filtered)
{
    float filtered;
    // 公式:本次输出 = alpha * 当前值 + (1-alpha) * 上一次输出
    filtered = ALPHA * current_data + (1 - ALPHA) * last_filtered;
    return filtered;
}



// ==============================
// 2. 一阶高通滤波(去漂移、提变化)
// 输入:当前原始数据,上一次输入,上一次输出
// 输出:本次滤波后数据
// ==============================
float high_pass_filter(float current_data, float last_data, float last_filtered)
{
    float filtered;
    // 公式:本次输出 = (1-alpha) * (上一次输出 + 当前输入 - 上一次输入)
    filtered = (1 - ALPHA) * (last_filtered + current_data - last_data);
    return filtered;
}


// 测试主函数
int main()
{
    // 模拟一组带漂移+噪声的原始数据(模拟传感器信号)
    float raw_data[] = {10.2, 10.3, 10.8, 10.1, 10.5,
                        11.2, 11.1, 11.6, 11.0, 11.3};

    int data_len = sizeof(raw_data) / sizeof(raw_data[0]);

    // 滤波变量初始化
    float last_low = raw_data[0];  // 低通上一帧结果
    float last_high = 0;           // 高通上一帧结果
    float last_in = raw_data[0];   // 高通上一帧输入

    printf("序号\t原始数据\t低通滤波\t高通滤波\n");
    printf("---------------------------------------------\n");

    for (int i = 0; i < data_len; i++)
    {
        // 低通滤波
        float out_low = low_pass_filter(raw_data[i], last_low);
        last_low = out_low;

        // 高通滤波
        float out_high = high_pass_filter(raw_data[i], last_in, last_high);
        last_in = raw_data[i];
        last_high = out_high;

        // 打印结果
        printf("%d\t%.2f\t\t%.2f\t\t%.2f\n",
               i, raw_data[i], out_low, out_high);
    }

    return 0;
}

C运行结果:

数据绘图展示(Python):

先装库:

cpp 复制代码
pip install matplotlib

再输代码运行:

python 复制代码
import matplotlib.pyplot as plt

# 修复中文显示问题
plt.rcParams["font.family"] = ["SimHei", "Microsoft YaHei", "Arial Unicode MS"]
plt.rcParams["axes.unicode_minus"] = False  # 修复负号显示

# C程序原始数据 & 对应滤波结果
x = [0,1,2,3,4,5,6,7,8,9]
raw  = [10.2, 10.3, 10.8, 10.1, 10.5, 11.2, 11.1, 11.6, 11.0, 11.3]
low  = [10.20, 10.21, 10.24, 10.23, 10.25, 10.30, 10.34, 10.40, 10.43, 10.47]
high = [0.00, 0.10, 0.57, -0.14, 0.27, 0.94, 0.85, 1.31, 0.70, 0.97]

plt.figure(figsize=(11,7))

# 1.原始信号
plt.subplot(3,1,1)
plt.plot(x, raw, color="#666666", marker="o", linewidth=2, label="原始传感器数据")
plt.title("原始信号(含波动+缓慢漂移)", fontsize=12)
plt.grid(True, alpha=0.3)
plt.legend()

# 2.低通滤波
plt.subplot(3,1,2)
plt.plot(x, low, color="#0066ff", marker="o", linewidth=2, label="一阶低通滤波(平滑去噪)")
plt.title("低通滤波结果:抑制毛刺、保留缓慢趋势", fontsize=12)
plt.grid(True, alpha=0.3)
plt.legend()

# 3.高通滤波
plt.subplot(3,1,3)
plt.plot(x, high, color="#ff2200", marker="o", linewidth=2, label="一阶高通滤波(提取变化量)")
plt.axhline(y=0, color='black', linestyle='--', alpha=0.5)
plt.title("高通滤波结果:去除基线、只保留信号变化幅度", fontsize=12)
plt.grid(True, alpha=0.3)
plt.legend()

plt.tight_layout()
plt.show()

绘图结果:

相关推荐
NPUQS3 小时前
【Unity 3D学习】Unity 与 Python 互通入门:点击按钮调用 Python(超简单示例)
学习·3d·unity
电子云与长程纠缠10 小时前
Godot学习05 - 播放与分离FBX动画
学习·游戏引擎·godot
蒸蒸yyyyzwd10 小时前
day3学习笔记
笔记·学习
red_redemption11 小时前
自由学习记录(143)
学习
楼田莉子12 小时前
MySQL数据库:MySQL的数据类型
数据库·学习·mysql
小陈phd13 小时前
系统架构师学习笔记(三)——计算机体系结构之存储系统
笔记·学习·系统架构
Rsun0455114 小时前
AI智能体学习路线
人工智能·学习
charlie11451419114 小时前
通用GUI编程技术——Win32 原生编程实战(十六)——Visual Studio 资源编辑器使用指南
开发语言·c++·ide·学习·gui·visual studio·win32
知识分享小能手14 小时前
MongoDB入门学习教程,从入门到精通,MongoDB查询(4)
数据库·学习·mongodb