Scipy库中FIR滤波器的应用

ops/2024/9/24 7:34:51/

  在上一篇文章《Scipy库中IIR滤波器的应用》中,我们阐述了利用Scipy库进行IIR滤波器设计的一些基本做法。在这篇文章中我们将进一步总结Scipy库在FIR滤波器设计中1的应用。

1. FIR滤波器基本概念
  在上篇文章中,我们在给出线性滤波器的差分方程喝系统函数的一般形式时指出FIR滤波器是一个无反馈的全零点型滤波器。设输入序列为 x n x_n xn,系数为 b m b_m bm,则滤波输出为
y n = ∑ m = 0 M b m x n − m (1) y_n=\sum_{m=0}^M b_m x_{n-m} \tag{1} yn=m=0Mbmxnm(1)
  上面的表达式本质上是抽头系数序列和输入序列的卷积。其中, M M M称为滤波器的阶数,一般 M M M阶FIR滤波器有 M + 1 M+1 M+1个抽头系数。
  在Scipy中可以调用scipy.signal.lfilter或scipy.signal.convolve函数来对输入序列进行FIR滤波。需要主要的是对于一个有限长输入序列 x 0 , x 1 , . . . , x N x_0,x_1,...,x_N x0,x1,...,xN,式(1)并没有指明当 n < M n < M n<M时如何处理。函数 scipy.signal.convolve中有一个入参mode可以用于指定上述问题的处理方法。比如当mode='valid’时,将严格按照(1)进行计算,当mode='same’时会对输入序列进行补零,使得输入和输出长度保持一致。
  FIR滤波器的频响可以调用scipy.signal.freqz得到,它的输入为抽头系数及频率点数,下面以滑动平均滤波器为例进行说明。函数freqz返回的是归一化角频率,范围是 0 − π 0-\pi 0π,如果已知信号采样率 f s f_s fs,可将其乘以 f s / ( 2 π ) f_s/(2\pi) fs/(2π)将横坐标转化为以Hz为单位的频率值。

import matplotlib.pyplot as plt
from scipy.signal import freqz
if __name__ == "__main__":for n in [3, 7, 21]:taps = np.full(n, fill_value=1.0 / n)w, h = freqz(taps, worN=2000)plt.plot(w, np.abs(h), label='n=%d' % n)plt.show()

在这里插入图片描述

图1.滑动平均滤波器的频响

2. FIR滤波器设计
  Scipy数据库中提供了四种FIR滤波器设计方法,分别是:
  a) 窗函数法:该方法首先计算理想FIR滤波器的冲激响应,然后对其进行加窗得到最终的滤波器冲激响应;
  b) 最小均方误差法:该方法使得设计的FIR滤波器频响与理想滤波器频响的均衡误差最小。
  c) Parks-McClellan法:该方法是一种等纹波设计方法,它使得设计的FIR滤波器和理想FIR滤波器频响的最大误差最小化。
  d) 线性规划法:该方法其实是Parks-McClellan法的一种线性规划解法。
  在详细描述上述方法之前,首先定义 ω \omega ω为角频率, A ( ω ) A(\omega) A(ω)为所设计的滤波器频响的实部。 D ( ω ) D(\omega) D(ω)为理想滤波器的频响, W ( ω ) W(\omega) W(ω)为权重向量,用于调整误差 A ( ω ) − D ( ω ) A(\omega)-D(\omega) A(ω)D(ω)的权重。

  (1) 窗函数法
  窗函数法的基本步骤是首先计算理想FIR滤波器的冲激响应,然后利用窗函数对其进行截断得到最终FIR滤波器的冲激响应。scipy.signal中有两个窗函数设计的函数firwin和firwin2。本小节中只展示firwin2的用法,firwin的用法将在后面介绍Kaiser窗函数设计法的时候讲到。
  在这边我们打算设计一个185阶的FIR滤波器,对采样率 f s = 2000 S a / s fs=2000Sa/s fs=2000Sa/s的信号进行滤波。这个滤波器整体表现为低通特性,它的过渡带是150Hz~175Hz。我们还希望这个滤波器在48Hz-72Hz之间有一个倒三角的凹坑,凹坑中心在60Hz处,且凹坑顶点处的增益为0.1。实现代码如下。firwin2函数的输入参数包括滤波器阶数频点(各个频率转折点,范围是0-fs)各个频点对应的增益奈奎斯特频率fs/2窗函数类型。下面的案例中对比了矩形窗、hamming窗和凯撒窗的结果。

import matplotlib.pyplot as plt
from scipy.signal import freqz, firwin2
if __name__ == "__main__":fs = 2000numtaps = 185freqs = [0, 48, 60, 72, 150, 175, 1000]gains = [1, 1, 0.1, 1, 1, 0, 0]taps_rect = firwin2(numtaps, freqs, gains, nyq=0.5 * fs, window=None)taps_hamming = firwin2(numtaps, freqs, gains, nyq=0.5 * fs, window='hamming')taps_kaiser = firwin2(numtaps,freqs, gains, nyq=0.5 * fs, window=('kaiser', 2.7))w_rect, h_rect = freqz(taps_rect, worN=2000)w_hamming, h_hamming = freqz(taps_hamming, worN=2000)w_kaiser, h_kaiser = freqz(taps_kaiser, worN=2000)plt.figure()plt.plot(freqs, gains, 'r--')plt.plot(w_rect * fs / (2 * np.pi), np.abs(h_rect), 'b')plt.plot(w_hamming * fs / (2 * np.pi), np.abs(h_hamming), 'y')plt.plot(w_kaiser * fs / (2 * np.pi), np.abs(h_kaiser), 'k')plt.legend(['ideal', 'rect', 'hamming', 'kaiser'])plt.xlabel('frequency(Hz)')plt.ylabel('gain')plt.show()

在这里插入图片描述

图2.窗函数设计法结果示意图

  (2) 最小均方误差法
  该方法的设计目标是使下面的表达式最小化:
∫ 0 π W ( ω ) ( A ( ω ) − D ( ω ) ) 2 d ω \int_0^{\pi}W(\omega)(A(\omega)-D(\omega))^2 d\omega 0πW(ω)(A(ω)D(ω))2dω
  在scipy库中,scipy.signal.firls函数实现了上述最优化问题。

未完待续…
未完待续…
未完待续…
未完待续…


http://www.ppmy.cn/ops/14401.html

相关文章

【SAP ME 26】SAP ME创建开发组件(DC)mobile

目录 1、说明 2、创建开发组件(DC) 3、相关性 4、公共部分 5、构建

MAC 安装miniconda

Conda Conda是一个开源跨平台语言无关的包管理与环境管理系统。由“连续统分析”基于BSD许可证发布。 Conda允许用户方便地安装不同版本的二进制软件包与该计算平台需要的所有库。还允许用户在不同版本的包之间切换、从一个软件仓库下载包并安装。 Conda是用Python语言开发&am…

[Java EE] 多线程(三):线程安全问题(上)

1. 线程安全 1.1 线程安全的概念 如果多线程环境下代码运行的结果不符合我们的预期,则我们说存在线程安全问题,即程序存在bug,反之,不存在线程安全问题. 1.2 线程不安全的原因 我们下面举出一个线程不安全的例子:我们想要在两个线程中对count进行操作 public class Demo9 …

缓存神器-JetCache

序言 今天和大家聊聊阿里的一款缓存神器 JetCache。 一、缓存在开发实践中的问题 1.1 缓存方案的可扩展性问题 谈及缓存&#xff0c;其实有许多方案可供选择。例如&#xff1a;Guava Cache、Caffine、Encache、Redis 等。 这些缓存技术都能满足我们的需求&#xff0c;但现…

基于python+django+mysql农业生产可视化系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

如何调节电脑屏幕亮度?让你的眼睛更舒适!

电脑屏幕亮度的调节对于我们的视力保护和使用舒适度至关重要。不同的环境和使用习惯可能需要不同的亮度设置。可是如何调节电脑屏幕亮度呢&#xff1f;本文将介绍三种不同的电脑屏幕亮度调节方法&#xff0c;帮助您轻松调节电脑屏幕亮度&#xff0c;以满足您的需求。 方法1&…

验证二叉搜索树 - LeetCode 热题 43

大家好&#xff01;我是曾续缘&#x1f618; 今天是《LeetCode 热题 100》系列 发车第 43 天 二叉树第 8 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜…

Python闭包:深入理解与应用场景解析

Python闭包&#xff1a;深入理解与应用场景解析 在Python中&#xff0c;闭包是一个强大的概念&#xff0c;它允许函数记住并访问所在作用域之外的变量。闭包通常由嵌套函数构成&#xff0c;内层函数引用了外层函数的变量&#xff0c;并且外层函数返回内层函数。本文将深入探讨…