IIR和FIR两种滤波器有什么区别?

2024-06-11 08:52
文章标签 区别 两种 滤波器 fir iir

本文主要是介绍IIR和FIR两种滤波器有什么区别?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概念的区分

IIR(Infinite Impulse Response,无限脉冲响应)和FIR(Finite Impulse Response,有限脉冲响应)滤波器是两种常见的数字信号处理滤波器类型,它们在结构、性能和用途上有显著区别:

结构差异:

IIR滤波器具有反馈结构,即滤波器的输出不仅取决于当前和过去输入信号的值,还包括过去的输出信号。这意味着IIR滤波器的冲激响应永远不会完全衰减到零,理论上无穷期延续。
FIR滤波器则不包含反馈环路,其输出只依赖于当前和过去的输入信号。FIR滤波器的冲激响应在有限时间内会衰减至零。


稳定性:

FIR滤波器总是稳定的,因为没有反馈回路,不存在发散的可能性。
IIR滤波器的稳定性取决于其极点位置,如果所有的极点都在单位圆内,则滤波器是稳定的;否则,可能会导致不稳定。


相位响应:

FIR滤波器具有线性相位响应,即所有频率的信号通过滤波器后,其相位延迟与频率成线性关系,这对于保持信号的相位同步和时间对齐很重要。
IIR滤波器一般具有非线性相位响应,除非特别设计,否则相位延迟会随着频率变化,这在某些应用中可能会带来问题。


滤波特性:

IIR滤波器因其反馈结构可以实现较高的滤波效率,用较少的阶数就能达到所需的滤波特性,比如陡峭的滚降特性或接近理想滤波器的响应曲线。
FIR滤波器虽然阶数较高时才能达到类似的效果,但因其线性相位和无发散风险,更适合需要精确相位和稳态无误差的场合。


设计灵活性:

FIR滤波器的设计通常更为直观和灵活,易于实现严格的带宽、阻带衰减和线性相位响应。
IIR滤波器可以基于经典滤波器设计方法(如巴特沃兹、切比雪夫等)实现特定频率响应,但其非线性相位特性增加了设计难度。


在工程实践中,选择IIR还是FIR滤波器通常取决于具体的应用需求。如果对相位线性度要求较高,或担心稳定性问题,通常会选择FIR滤波器。而在对计算资源有限,需要以较低阶数实现较强滤波效果,且对相位非线性有一定的容忍度时,IIR滤波器则是一个合适的选择。在现代DSP应用中,由于计算能力的增强,FIR滤波器因其稳定性、线性相位和易于设计的特点而越来越受到青睐。

C语言实现

实现IIR(无限脉冲响应)和FIR(有限脉冲响应)带通滤波器通常涉及到计算每个新样本点时的滤波操作。以下是对这两种滤波器的基本实现框架的概述以及示例C代码片段:

IIR带通滤波器

IIR滤波器通常通过递归的方式实现,即输出不仅取决于当前的输入样本,还取决于过去若干个输入样本以及过去若干个输出样本。巴特沃斯、切比雪夫、椭圆滤波器等经典滤波器结构都可以被用来设计IIR带通滤波器。以下是一个二阶Butterworth IIR带通滤波器的例子:

#include <math.h>// 假设我们已经有了滤波器的系数
#define B0 0.5 * (1.0 + sqrt(2)) // 振幅系数B0
#define B1 0.0                  // 振幅系数B1
#define B2 (-1.0 * B0)          // 振幅系数B2
#define A1 (-1.0 * sqrt(2) / 2.0) // 阻尼系数A1
#define A2 (1.0 - sqrt(2) / 2.0)  // 阻尼系数A2// 初始化历史状态变量
float x_n_1 = 0.0; // 上一次输入样本
float x_n_2 = 0.0; // 上上次输入样本
float y_n_1 = 0.0; // 上一次输出样本
float y_n_2 = 0.0; // 上上次输出样本// IIR带通滤波器核心函数
float iir_bandpass_filter(float input)
{// 计算当前输出float output = B0 * input + B1 * x_n_1 + B2 * x_n_2 - A1 * y_n_1 - A2 * y_n_2;// 更新历史状态x_n_2 = x_n_1;x_n_1 = input;y_n_2 = y_n_1;y_n_1 = output;return output;
}// 使用滤波器
int main()
{float input_signal[signal_length];float output_signal[signal_length];// ... 填充input_signal...for (int i = 0; i < signal_length; ++i){output_signal[i] = iir_bandpass_filter(input_signal[i]);}// ... 处理output_signal...return 0;
}


注意,实际使用时你需要根据具体的设计参数(如截止频率、品质因数等)计算合适的滤波器系数B0、B1、B2、A1和A2。

FIR带通滤波器

FIR滤波器没有反馈部分,仅依赖于当前和过去若干个输入样本。带通FIR滤波器通常通过卷积实现,系数来自于窗函数法或其他设计方法。
 

#include <stdio.h>// 滤波器系数数组h[]
#define FILTER_ORDER 51 // FIR滤波器阶数
float h[FILTER_ORDER]; // 初始化滤波器系数
// ...省略了根据设计要求填充滤波器系数的过程...// FIR带通滤波器核心函数
void fir_bandpass_filter(float input, float* state, float* output)
{static const int STATE_SIZE = FILTER_ORDER - 1; // FIR滤波器的状态大小static float input_state[STATE_SIZE]; // 存储过去输入样本的状态// 移除最早的一个输入样本,添加最新的输入样本memmove(input_state + 1, input_state, sizeof(float) * (STATE_SIZE - 1));input_state[0] = input;// FIR滤波输出计算*output = 0.0;for (int i = 0; i < FILTER_ORDER; ++i){*output += h[i] * input_state[i];}
}// 使用滤波器
int main()
{float input_signal[signal_length];float output_signal[signal_length];float filter_state[FILTER_ORDER - 1] = {0}; // 初始化状态为零// ... 填充input_signal...for (int i = 0; i < signal_length; ++i){fir_bandpass_filter(input_signal[i], filter_state, &output_signal[i]);}// ... 处理output_signal...return 0;
}


同样,这里的FIR滤波器系数`h[]`需要根据目标频率响应曲线设计得到。在实际项目中,可以使用像MATLAB、Python的SciPy库或者其他DSP工具设计滤波器并获取这些系数。

请确保根据实际应用调整滤波器阶数、类型和系数,同时注意边界条件的处理,特别是对于实时流数据的第一段样本,可能需要预先填充足够的“零”值来初始化滤波器状态。

这篇关于IIR和FIR两种滤波器有什么区别?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1050712

相关文章

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

Python读取TIF文件的两种方法实现

《Python读取TIF文件的两种方法实现》本文主要介绍了Python读取TIF文件的两种方法实现,包括使用tifffile库和Pillow库逐帧读取TIFF文件,具有一定的参考价值,感兴趣的可以了解... 目录方法 1:使用 tifffile 逐帧读取安装 tifffile:逐帧读取代码:方法 2:使用

python中json.dumps和json.dump区别

《python中json.dumps和json.dump区别》json.dumps将Python对象序列化为JSON字符串,json.dump直接将Python对象序列化写入文件,本文就来介绍一下两个... 目录1、json.dumps和json.dump的区别2、使用 json.dumps() 然后写入文

native和static native区别

本文基于Hello JNI  如有疑惑,请看之前几篇文章。 native 与 static native java中 public native String helloJni();public native static String helloJniStatic();1212 JNI中 JNIEXPORT jstring JNICALL Java_com_test_g

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

javascript中break与continue的区别

在javascript中,break是结束整个循环,break下面的语句不再执行了 for(let i=1;i<=5;i++){if(i===3){break}document.write(i) } 上面的代码中,当i=1时,执行打印输出语句,当i=2时,执行打印输出语句,当i=3时,遇到break了,整个循环就结束了。 执行结果是12 continue语句是停止当前循环,返回从头开始。

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

ActiveMQ—Queue与Topic区别

Queue与Topic区别 转自:http://blog.csdn.net/qq_21033663/article/details/52458305 队列(Queue)和主题(Topic)是JMS支持的两种消息传递模型:         1、点对点(point-to-point,简称PTP)Queue消息传递模型:         通过该消息传递模型,一个应用程序(即消息生产者)可以