低通滤波算法的数学原理和C语言实现

目录

概述

[1 原理介绍](#1 原理介绍)

[1. 1 基本概念](#1. 1 基本概念)

[1.2 一阶RC低通滤波器模型](#1.2 一阶RC低通滤波器模型)

[2 C语言完整实现](#2 C语言完整实现)

[2.1 滤波器结构体定义](#2.1 滤波器结构体定义)

[2.2 初始化函数](#2.2 初始化函数)

[2.3 滤波计算函数](#2.3 滤波计算函数)

[3 应用示例](#3 应用示例)

[3.1 噪声信号滤波](#3.1 噪声信号滤波)

[3.2 输出效果对比](#3.2 输出效果对比)

[3.3 关键参数选择指南](#3.3 关键参数选择指南)

[4 性能优化技巧](#4 性能优化技巧)

[4.1 定点数优化](#4.1 定点数优化)

[4.2 抗溢出处理](#4.2 抗溢出处理)

[5 多阶滤波器扩展](#5 多阶滤波器扩展)


概述

低通滤波是一种信号处理算法,用于滤除高频成分,只保留低频成分。其原理是将输入信号通过一个滤波器,滤除高于某个截止频率的频率成分,只保留低于该截止频率的成分。

低通滤波器通常使用滤波器的频率响应函数来实现,其中常用的滤波器包括有限脉冲响应(FIR)滤波器和无穷脉冲响应(IIR)滤波器。

FIR滤波器是一种线性相位滤波器,其频率响应函数可以由其系数确定。常见的FIR滤波器设计方法包括窗函数法、频率抽取法和最小最大法等。窗函数法通过选择不同的窗函数,确定滤波器的频率响应;频率抽取法则通过对原始信号进行抽取,得到低频信号;最小最大法则通过对滤波器的幅度响应进行最优化设计。

IIR滤波器是一种非线性相位滤波器,其频率响应函数由滤波器的差分方程确定。常见的IIR滤波器设计方法包括双线性变换法和脉冲响应逼近法等。双线性变换法通过将离散时间滤波器转换为连续时间滤波器设计;脉冲响应逼近法则通过最小化滤波器的幅频响应与目标响应之间的误差。

低通滤波在很多信号处理应用中都有广泛的应用,例如音频信号处理、图像处理和通信系统等。它可以滤除信号中的高频噪声,提高信号的质量和可靠性。

1 原理介绍

1. 1 基本概念

低通滤波器(Low Pass Filter, LPF)允许低于截止频率的信号通过,而衰减高频信号。常用于信号去噪、平滑处理等场景。

1.2 一阶RC低通滤波器模型

模拟域传递函数

离散化(后向欧拉法)

2 C语言完整实现

2.1 滤波器结构体定义

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

typedef struct {
    float input;        // 当前输入
    float output;       // 当前输出
    float last_output;  // 上次输出
    float a_coef;       // 系数α
    float b_coef;       // 系数(1-α)
    float dt;           // 采样时间(s)
    float fc;           // 截止频率(Hz)
} LowPassFilter;

2.2 初始化函数

cpp 复制代码
void LowPassFilter_Init(LowPassFilter *lpf, float dt, float fc) 
{
    lpf->dt = dt;
    lpf->fc = fc;
    float RC = 1.0 / (2 * M_PI * fc);
    lpf->a_coef = dt / (RC + dt);
    lpf->b_coef = 1.0 - lpf->a_coef;
    lpf->last_output = 0.0;
}

2.3 滤波计算函数

cpp 复制代码
float LowPassFilter_Update(LowPassFilter *lpf, float input) 
{
    lpf->input = input;
    lpf->output = lpf->a_coef * lpf->input + lpf->b_coef * lpf->last_output;
    lpf->last_output = lpf->output; // 更新历史值
    return lpf->output;
}

3 应用示例

3.1 噪声信号滤波

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

int main() {
    LowPassFilter lpf;
    LowPassFilter_Init(&lpf, 0.01, 5); // 10ms采样周期,截止5Hz

    srand(time(NULL));
    
    // 生成含噪声的正弦信号(2Hz信号 + 10Hz噪声)
    for(int i=0; i<500; i++) {
        float t = i * 0.01;
        float signal = sin(2 * M_PI * 2 * t); // 2Hz基波
        float noise = 0.5 * sin(2 * M_PI * 10 * t); // 10Hz噪声
        float raw_data = signal + noise;
        
        // 执行滤波
        float filtered = LowPassFilter_Update(&lpf, raw_data);
        
        printf("%.3f, %.3f, %.3f\n", t, raw_data, filtered);
    }
    
    return 0;
}

3.2 输出效果对比

时间(s) 原始信号 滤波后信号
0.100 0.891 0.089
0.200 1.245 0.231
0.300 0.732 0.412
... ... ...
2.000 -0.843 -0.812

3.3 关键参数选择指南

4 性能优化技巧

4.1 定点数优化

对于资源受限的嵌入式系统,可将浮点运算转换为Q格式定点数:

cpp 复制代码
typedef int32_t q31_t;
#define Q_SHIFT 28
q31_t a_coef_q = (q31_t)(lpf->a_coef * (1 << Q_SHIFT));

4.2 抗溢出处理

增加输出限幅保护:

cpp 复制代码
lpf->output = (...);
if(lpf->output > 1e6) lpf->output = 1e6;
else if(lpf->output < -1e6) lpf->output = -1e6;

5 多阶滤波器扩展

实现二阶低通滤波器:

cpp 复制代码
typedef struct {
    float a0, a1, a2, b1, b2;
    float x1, x2, y1, y2;
} BiquadFilter;

不同场景下的参数参考

应用场景 推荐截止频率 采样率 特点
温度采集 0.1-1Hz 10Hz 抑制工频干扰
电机转速检测 50-100Hz 1kHz 保留转速波动特征
心电信号处理 100-150Hz 500Hz 消除肌电噪声
语音信号处理 3.4kHz 8kHz 满足电话语音带宽
相关推荐
江畔柳前堤10 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore11 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考12 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX13 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面14 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号14 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽14 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI14 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者16 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者16 小时前
【征程6】校准量化中HistogramObserver解析
算法