低通滤波算法的数学原理和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 满足电话语音带宽
相关推荐
KaMeidebaby10 小时前
卡梅德生物技术快报|酵母双杂交 cDNA 文库构建与蛋白互作筛选流程
服务器·前端·数据库·人工智能·算法
sheeta199810 小时前
LeetCode 每日一题笔记 日期:2026.05.27 题目:3121. 统计特殊字母的数量 II
笔记·算法·leetcode
ST——Jess10 小时前
年度行业趋势研究报告:泛心理数字化赛道“流日推演”的算法困境与高保真交互范式重构
人工智能·算法·架构
Tisfy10 小时前
LeetCode 3300.替换为数位和以后的最小元素:一次遍历
数学·算法·leetcode·模拟
garmin Chen10 小时前
LeetcodeHot100打卡(14、合并空间,15、轮转数组,16、除了自身以外数组乘积,17.缺失的第一个整数)
java·笔记·学习·算法
elseif12311 小时前
【C++】vector 详细版
开发语言·c++·算法
变量未定义~11 小时前
既约分数、阶乘约数、逆元、最大质因子个数【算法赛】
算法
KaMeidebaby11 小时前
卡梅德生物技术快报|Western Blot 实验应用:肺肠轴机制研究全流程技术解析
前端·数据库·人工智能·算法·百度
AhriProGramming11 小时前
计算机科普故事会-<2>见微知著
算法