[python] 使用python设计滤波器

使用python设计滤波器

文章目录

  • 使用python设计滤波器
    • 完整滤波器设计代码(未经完整验证,博主还在不断完善中)
    • 关键原理与代码对应说明
      • 1. 滤波器类型选择
      • 2. 阶数估算原理
      • 3. 性能分析技术
      • 4. 设计参数调整指南

习惯了python后,matlab逐渐成为了牛夫人,尤其是漂亮国对龙国制裁后,我作为有骨气其的码农,虽然有和谐版的matlab可用,但是终究是放不下码农的尊严,不到万不得一,已经很少用matlab了。绝大部分仿真工作,都已经移步到python,但最近要进行滤波器设计,为了不使用matlab的fdatool,便尝试着用python设计滤波器。

闲话少说,代码说话:


完整滤波器设计代码(未经完整验证,博主还在不断完善中)

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from matplotlib.ticker import EngFormatter# 设计参数
fs = 10000       # 采样率 10kHz
nyq = fs / 2     # 奈奎斯特频率
passband = 1500  # 通带截止频率 (Hz)
stopband = 2000  # 阻带截止频率 (Hz)
pass_ripple = 1  # 通带波动 (dB)
stop_atten = 40  # 阻带衰减 (dB)# 计算归一化频率
wp = passband / nyq
ws = stopband / nyqdef design_iir_filter():"""设计椭圆IIR滤波器"""# 计算最小阶数和自然频率order, wn = signal.ellipord(wp, ws, pass_ripple, stop_atten)# 设计椭圆滤波器b, a = signal.ellip(order, pass_ripple, stop_atten, wn, btype='low', analog=False)return b, a, orderdef design_fir_filter():"""设计FIR滤波器(凯塞窗方法)"""# 计算过渡带宽度width = abs(stopband - passband) / nyq# 估算凯塞窗参数A = stop_attenbeta = 0.1102*(A - 8.7) if A > 50 else 0.5842*(A - 21)**0.4 + 0.07886*(A - 21)# 计算所需阶数numtaps = int((A - 8) / (2.285 * 2 * np.pi * width)) + 1# 设计FIR滤波器taps = signal.firwin(numtaps, wn=passband/nyq, window=('kaiser', beta), pass_zero='lowpass')return taps, numtapsdef analyze_filter(b, a=None):"""分析滤波器性能"""fig, (ax_mag, ax_phase, ax_grp, ax_zp) = plt.subplots(4, 1, figsize=(10, 12))# 幅频响应w, h = signal.freqz(b, a, worN=8000, fs=fs)ax_mag.plot(w, 20 * np.log10(np.abs(h)), color='blue')ax_mag.set_title('幅频响应')ax_mag.set_ylabel('幅度 (dB)')ax_mag.grid(True, which='both', linestyle='--')ax_mag.axvline(passband, color='g', linestyle='--', alpha=0.7)ax_mag.axvline(stopband, color='r', linestyle='--', alpha=0.7)ax_mag.set_ylim([-stop_atten-20, 5])# 相频响应angles = np.unwrap(np.angle(h))ax_phase.plot(w, angles, color='green')ax_phase.set_title('相频响应')ax_phase.set_ylabel('相位 (弧度)')ax_phase.grid(True)# 群延迟grp_delay = -np.diff(angles) / np.diff(w)ax_grp.plot(w[:-1], grp_delay, color='red')ax_grp.set_title('群延迟')ax_grp.set_ylabel('采样点数')ax_grp.grid(True)# 零极点图if a is not None:  # IIR滤波器z, p, k = signal.tf2zpk(b, a)ax_zp.scatter(np.real(z), np.imag(z), marker='o', facecolors='none', edgecolors='b', s=80)else:  # FIR滤波器z = np.roots(b)p = np.zeros(len(z))ax_zp.scatter(np.real(z), np.imag(z), marker='o', facecolors='none', edgecolors='b', s=80)ax_zp.scatter(np.real(p), np.imag(p), marker='x', color='r', s=80)unit_circle = plt.Circle((0,0), radius=1, fill=False, color='gray', linestyle='--')ax_zp.add_patch(unit_circle)ax_zp.set_title('零极点图')ax_zp.set_xlabel('实部')ax_zp.set_ylabel('虚部')ax_zp.grid(True)ax_zp.axis('equal')ax_zp.axhline(0, color='black', linewidth=0.5)ax_zp.axvline(0, color='black', linewidth=0.5)plt.tight_layout()return fig# 主程序
if __name__ == "__main__":# 设计IIR滤波器b_iir, a_iir, iir_order = design_iir_filter()print(f"IIR滤波器阶数: {iir_order}")# 设计FIR滤波器fir_taps, fir_order = design_fir_filter()print(f"FIR滤波器阶数: {fir_order}")# 分析IIR滤波器fig_iir = analyze_filter(b_iir, a_iir)fig_iir.suptitle('椭圆IIR滤波器分析', fontsize=16)# 分析FIR滤波器fig_fir = analyze_filter(fir_taps)fig_fir.suptitle('FIR滤波器分析', fontsize=16)# 应用滤波器示例t = np.linspace(0, 1, fs)  # 1秒时长sig = np.sin(2*np.pi*1000*t) + 0.5*np.sin(2*np.pi*3000*t)# IIR滤波filtered_iir = signal.lfilter(b_iir, a_iir, sig)# FIR滤波filtered_fir = signal.lfilter(fir_taps, 1.0, sig)# 绘制结果plt.figure(figsize=(10, 6))plt.plot(t[:500], sig[:500], 'b-', label='原始信号')plt.plot(t[:500], filtered_iir[:500], 'r-', label='IIR滤波后')plt.plot(t[:500], filtered_fir[:500], 'g-', label='FIR滤波后')plt.title('时域滤波效果对比 (前500点)')plt.xlabel('时间 (秒)')plt.ylabel('幅度')plt.legend()plt.grid(True)plt.tight_layout()plt.show()

关键原理与代码对应说明

1. 滤波器类型选择

  • IIR滤波器:椭圆滤波器(Elliptic)提供最陡峭过渡带

    order, wn = signal.ellipord(wp, ws, pass_ripple, stop_atten)
    b, a = signal.ellip(order, pass_ripple, stop_atten, wn, btype='low')
    
    • ellipord计算最小阶数和自然频率
    • 椭圆滤波器在通带/阻带均有等波纹特性
  • FIR滤波器:凯塞窗(Kaiser)提供参数化控制

    beta = 0.1102*(A - 8.7)  # 窗形参数计算
    taps = signal.firwin(numtaps, cutoff, window=('kaiser', beta))
    
    • 凯塞窗通过beta控制主瓣宽度和旁瓣衰减平衡

2. 阶数估算原理

  • IIR阶数估算
    N = K ( ω s ) K ( 1 − ω p 2 ) K ( ω p ) K ( 1 − ω s 2 ) N = \frac{K(\omega_s)K(\sqrt{1-\omega_p^2})}{K(\omega_p)K(\sqrt{1-\omega_s^2})} N=K(ωp)K(1ωs2 )K(ωs)K(1ωp2 )
    其中K为第一类完全椭圆积分

  • FIR阶数估算
    N ≈ A − 8 2.285 ⋅ Δ ω N \approx \frac{A - 8}{2.285 \cdot \Delta\omega} N2.285ΔωA8
    Δ ω \Delta\omega Δω为过渡带宽度,A为阻带衰减(dB)

3. 性能分析技术

  • 幅频响应signal.freqz计算复数频率响应

    w, h = signal.freqz(b, a, worN=8000, fs=fs)
    20*np.log10(np.abs(h))  # 转换为dB
    
  • 相位特性

    angles = np.unwrap(np.angle(h))  # 解卷绕相位
    
  • 群延迟:相位导数计算

    -np.diff(angles)/np.diff(w)  # 群延迟 = -dφ/dω
    
  • 稳定性分析

    • IIR:极点是否在单位圆内
    • FIR:恒稳定(全零点系统)

4. 设计参数调整指南

  1. 过渡带陡度

    • IIR:增加阶数
    • FIR:增加窗长度
  2. 阻带衰减

    • IIR:增加stop_atten参数
    • FIR:增大凯塞窗的beta
  3. 计算效率

    • IIR:阶数低但非线性相位
    • FIR:高阶但线性相位

此方案应该能替代MATLAB FDATool的核心功能,提供从设计到分析的完整工作流。可根据具体应用调整滤波器类型(低通/高通/带通)和设计参数。但是比起FDATool的可视化设计,还是有明显的不足,需要不断完善。


研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/909144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac电脑.sh文件,用来清除git当前分支

#!/bin/bashecho "正在检查Git仓库..." if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; thenecho "错误:当前目录不是Git仓库!"exit 1 fiecho "警告:这将丢弃所有未提交的更改和本地提交&am…

Bash (Bourne Again SHell)

Unix/Linux 系统中最常用的命令行解释器之一,它是原始 Bourne shell (sh) 的增强版本。以下是 Bash 的详细解释: 1. Bash 基础 1.1 什么是 Bash 一个命令行解释器,用于执行用户输入的命令支持脚本编程,可以编写复杂的自动化任务…

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…

AIStor 的模型上下文协议 (MCP) 服务器: 工作原理

在本系列的前几篇博文中,我们讨论了MinIO AIStor 模型上下文协议 (MCP) 服务器的用户级和管理员级功能。在第一篇博文中,我们学习了如何查看存储桶的内容、分析对象并标记它们以便将来处理。在第二篇博文中,我们还学习了如何使用管理员命令以…

Excel 怎么让透视表以正常Excel表格形式显示

目录 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总

汇编语言深度指南:从基础到字符串操作

基础知识 CPU简介 CPU是计算机的核心,负责: 执行机器指令:解码并执行二进制指令 mov eax, 5 ; 将值5移动到EAX寄存器暂存少量数据:通过内部寄存器快速存取访问存储器:读写内存数据 mov [0x1000], eax ; 将EAX值…

树莓派5-ubuntu 24.04 安装 ros环境

在开始安装ros环境前,需要确保已经准备好了以下操作 1.树莓派5开发板,已经烧录了 ubuntu 24.04,并做好了一些基础配置,如:远程访问配置,语言配置,网络配置等 2.新手建议在上面安装一个宝塔面板…

【狂飙AGI】第2课:大模型方向市场分析

目录 (一)产业规模(二)政策引导(三)人才需求(四)工作年限(五)年薪分析(六)薪资情况分析(七)地域及匹配薪资&am…

word用endnote插入国标参考文献

1.在endnote中先设置output style为我的GB格式 参考 Endnote使用——参考文献的插入及引用_endnote怎么引用参考文献-CSDN博客 已经修改好的GB导出格式:Chinese Std GBT7714 (numeric)-spx.ens Peixuan Shu/Chinese_Std_GBT7714 - 码云 - 开源中国 把这个style…

Peiiieee的Linux笔记(1)

基本指令 1. ls指令 语法:ls [选项][目录或文件] 功能:对于目录,该命令列出该目录下的所有子目录与文件。对于文件,将列出文件名以及其它信息。 -a:列出目录下的所有文件,包括以.开头的隐含文件。 -l&am…

Docker快速构建并启动Springboot程序,快速发布和上线/

Docker部署SpringBoot 1.工作木目录:/mnts/jar_work/vx_kefu/ruoyi_ruoyiwechatinfo 里面的目录是lib文件夹,logs文件夹,Dockerfile文件,SpringBoot的jar包,start.sh的命令,stop.sh的命令,tpid文件进程。 …

RT-Thread Studio 配置使用详细教程

文章目录 一、新建工程1.1 创建基于芯片的工程1.1.1 选择创建的rtt版本1.1.2 配置工程基本属性1.1.3 初创工程目录结构1.1.4 修改时钟配置1.1.5 配置调试下载器 1.2 创建基于开发板的工程 二、配置内核三、配置组件四、配置软件包五、适配配置六、其它问题 一、新建工程 1.1 创…

React 中的 useCallback 入门指南:是真需要,还是假怪?

在学习 React 时,很多人初步接触 useCallback 都有一个同样的疑问: “useCallback 到底是干啥的?不是简单地就是‘缓存一个函数’吗?我一直不明白它真正有什么用。” 这篇文章就来给你一个全方位、实操、有例实的 useCallback 入门…

14.计算机网络End

计算机网络end 一、概念 网络协议三要素:语法、语义、同步TCP/IP中为运输层提供服务的层级:网际层计算机网络性能指标(答5个即可): 带宽时延吞吐量往返时间(RTT)利用率 交换式以太网用户带宽&…

Next.js + Supabase = 快速开发 = 高速公路

Next.js Supabase介绍一下这2个好的,直说重点: ✅ Next.js:React 的“终极形态” 一句话概括: Next.js 是基于 React 的 Web 框架,帮你快速构建全栈应用,支持 SSR(服务端渲染)、AP…

机器学习用于算法交易(Matlab实现)

机器学习用于算法交易(Matlab实现) 摘要 随着金融市场的复杂性和交易量的不断增长,传统交易方式逐渐暴露出局限性,算法交易因其高效性和精准性已成为主流趋势。在此背景下,将机器学习融入算法交易具有重要的研究意义…

day64—回溯—组合数(LeetCode-77)

题目描述 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ] 示例 2: 输入&#xff1a…

机器学习与深度学习21-信息论

目录 前文回顾1.信息上的概念2.相对熵是什么3.互信息是什么4.条件熵和条件互信息5.最大熵模型6.信息增益与基尼不纯度 前文回顾 上一篇文章链接:地址 1.信息上的概念 信息熵(Entropy)是信息理论中用于度量随机变量不确定性的概念。它表示了…

chrome138版本及以上el-input的textarea输入问题

描述 项目基于vue2 element UI 问题简述&#xff1a;Chrome138及以上版本&#xff0c;把组件中的el-input的textarea的disabled属性从true设为false&#xff0c;无法输入 封装了一套表单输入组件&#xff0c;其中的textarea如下&#xff1a; <div v-if"item.type te…

TCP/IP 网络编程 | 服务端 客户端的封装

设计模式 文章目录 设计模式一、socket.h 接口&#xff08;interface&#xff09;二、socket.cpp 实现&#xff08;implementation&#xff09;三、server.cpp 使用封装&#xff08;main 函数&#xff09;四、client.cpp 使用封装&#xff08;main 函数&#xff09;五、退出方法…