Python音频处理-啥叫滤波器

简介: 本文介绍了高通、低通滤波器及三角滤波器的工作原理与应用,并通过Python代码展示了滤波器组的设计与实现,帮助理解滤波在信号处理中的作用。

滤波的主要目的是减少噪声与干扰对数据的影响,让数据更加接近真实值。

比如常说的:

“高通滤波器”,就是高频通过,低频去掉的滤波器。

“低通滤波器”,就是低频通过,高频去掉的滤波器。

本文主要介绍: 高低通滤波器,三角滤波器,滤波器组 等。

# 准备
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal
# 定义一个方波
sr = 16_000
T = 4
x = np.linspace(0, T, T * sr, endpoint=False)
y = 1 * np.sign(np.sin(2 * np.pi * 0.5 * x))
# 绘制
plt.figure(figsize=(8, 2))
plt.plot(y)
plt.show()

image.png

高/低通滤波器

# 基准频率(HZ)
cutoff_hz = 5
nyquist = 0.5 * sr
normalized_cutoff = cutoff_hz / nyquist

# 低通滤波,留下低于 cutoff_hz 的频率
sos_low = signal.butter(
    8, 
    normalized_cutoff,
    btype='low',
    output='sos'
)
y_out_low = signal.sosfiltfilt(sos_low, y)
print(f"sos_low.shape : {sos_low.shape}")
print(f"y.shape : {y.shape}")
print(f"y_out_low.shape : {y_out_low.shape}")

# 高通滤波, 留下高于 cutoff_hz 的频率
sos_high = signal.butter(
    8,
    normalized_cutoff,
    btype='high',
    output='sos'
)
y_out_high = signal.sosfiltfilt(sos_high, y)
print(f"sos_high.shape : {sos_high.shape}")
print(f"y.shape : {y.shape}")
print(f"y_out_high.shape : {y_out_high.shape}")

sos_low.shape : (4, 6)

y.shape : (64000,)

y_out_low.shape : (64000,)

sos_high.shape : (4, 6)

y.shape : (64000,)

y_out_high.shape : (64000,)

# 绘图对比
_, axs = plt.subplots(4, 1)
axs[0].plot(y)
axs[1].plot(y_out_low)
axs[2].plot(y_out_high)
axs[3].plot(y_out_low + y_out_high)
plt.tight_layout()
plt.show()

image.png

mse = np.square(y_out_low + y_out_high - y).mean()
mse

4.5419663300030064e-07

如上对比可知: 高通滤波剩余信号 + 低通滤波剩余信号 = 原始信号

三角滤波器

这里的实验:

  • 利用快速傅里叶变换提取方波主要频率
  • 然后自定义一个三角滤波器
  • 让方波主要频率通过三角滤波器
  • 最后对比三角滤波器的滤波效果。

主要频率提取

# 信号长度
n = len(y)
# 傅里叶变换
y_fft = np.fft.fft(y)
y_freq = np.fft.fftfreq(n, 1 / sr)
y_fft = y_fft[:n//2]
y_freq = y_freq[:n//2]
# 信号能量
magnitude = 2.0 * np.abs(y_fft) / n
# 提取主要频率
threshold = 0.1
mask = magnitude > threshold
detected_freqs = y_freq[mask]
detected_amps = magnitude[mask]
# 绘制频率图
plt.figure(figsize=(5, 3))
plt.plot(detected_freqs, detected_amps)
for xi, yi in zip(detected_freqs, detected_amps):
    plt.text(xi, yi, f"({xi},{yi:.2f})", ha='center', va='bottom')
plt.grid(True)
plt.show()

image.png

三角滤波器

# 三角滤波器生成方法
def triangular_filter(freqs, left, center, right):
    filter_response = np.zeros_like(freqs)
    # 上升部分
    rising = (freqs >= left) & (freqs < center)
    filter_response[rising] = (freqs[rising] - left) / (center - left)
    # 下降部分
    falling = (freqs >= center) & (freqs <= right)
    filter_response[falling] = (right - freqs[falling]) / (right - center)
    return filter_response

# 创建一个三角滤波器
frequencies = np.linspace(0, max(detected_freqs), len(detected_freqs))
print(f"frequencies : {frequencies}")
filter_response = triangular_filter(frequencies, 0, 2.2, 4.4)
print(f"filter_response : {filter_response}")
plt.plot(frequencies, filter_response)
plt.show()

frequencies : [0.  1.1 2.2 3.3 4.4 5.5]

filter_response : [0.  0.5 1.  0.5 0.  0. ]

image.png

滤波效果对比

# 滤波操作:过滤频率
filter_freqs = detected_freqs * filter_response
print(f"detected_freqs : {detected_freqs}")
print(f"filter_response : {filter_response}")
print(f"filter_freqs : {filter_freqs}")

detected_freqs : [0.5 1.5 2.5 3.5 4.5 5.5]

filter_response : [0.  0.5 1.  0.5 0.  0. ]

filter_freqs : [0.   0.75 2.5  1.75 0.   0.  ]

# fft主要频率重建
re_wave = np.zeros_like(y)
for freq, amp in zip(detected_freqs, detected_amps):
    re_wave += amp * np.sin(2 * np.pi * freq * x)
# fft主要频率 进过三角滤波器之后,重建
re_filter_wave = np.zeros_like(y)
for freq, amp in zip(filter_freqs, detected_amps):
    re_filter_wave += amp * np.sin(2 * np.pi * freq * x)
# 绘图对比
plt.figure(figsize=(9, 3))
plt.plot(x, y, label='y')
plt.plot(x, re_wave, label='Rebuilded Wave')
plt.plot(x, re_filter_wave, label='Rebuilded Filter Wave')
plt.tight_layout()
plt.grid(True)
plt.legend()
plt.show()

image.png

好吧,这个图,似乎看不出滤波器什么的内容。

不过(滤波操作:过滤频率)的数字,可以仔细看看。

filter_freqs = detected_freqs * filter_response

image.png

滤波器组

单纯的 filter_response 是一个滤波器,一般只对一个小范围的频率进行滤波。

可以组建滤波器组,对所有范围的频率进行过滤。

# 基本参数
sample_rate = 16000
n_fft = 512
n_mels = 64
f_min = 0.0
f_max = sample_rate / 2.0
n_freqs = int(n_fft // 2 + 1)
# 所有频率
all_freqs = np.linspace(0, sample_rate / 2.0, n_freqs)
# 目标刻度
t_pts = np.linspace(f_min, f_max, n_mels + 2)

# 创建三角滤波器组
def create_triangular_fbank(all_freqs, f_pts):
    # 滤波器
    filter_fbank = np.zeros((len(all_freqs), len(f_pts) - 2))
    # 实现三角滤波器
    for i in range(n_mels):
        left = t_pts[i]
        center = t_pts[i+1]
        right = t_pts[i+2]
        # up
        up = (all_freqs >= left) & (all_freqs < center)
        filter_fbank[up, i] = (all_freqs[up] - left) / (center - left)
        # down
        down = (all_freqs >= center) & (all_freqs <= right)
        filter_fbank[down, i] = (right - all_freqs[down]) / (right - center)
    return filter_fbank
# 创建滤波器组
filter_fbank = create_triangular_fbank(all_freqs, t_pts)
print(filter_fbank.T.shape)

(64, 257)

# 绘制滤波器
plt.imshow(filter_fbank[:, :10].T, aspect='auto')
plt.show()

image.png

奇怪,三角滤波器组,的三角去哪儿了?

好吧,图应该这样画:

# 绘制三角滤波器组
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for i in range(filter_fbank.shape[1]):
    x = np.full(filter_fbank.shape[0], i)
    y = np.arange(filter_fbank.shape[0])
    z = filter_fbank[:, i]
    # 绘制
    ax.plot(x, y, z)
    # 只绘制10条:filter_fbank[:, :10].T
    if i == 10:
        break
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.view_init(elev=20, azim=-30)
plt.show()

image.png

相关文章
|
计算机视觉 Python
Opencv学习笔记(一):如何将得到的图片保存在指定目录以及如何将文件夹里所有图片以数组形式输出
这篇博客介绍了如何使用OpenCV库在Python中将图片保存到指定目录,以及如何将文件夹中的所有图片读取并以数组形式输出。
1159 0
Opencv学习笔记(一):如何将得到的图片保存在指定目录以及如何将文件夹里所有图片以数组形式输出
|
4月前
|
人工智能 Linux API
零基础OpenClaw(Clawdbot)部署图文指南:无影云电脑/本地安装+阿里云百炼API配置及避坑指南
OpenClaw(曾用名Clawdbot、Moltbot)是2026年开源社区热度极高的AI Agent自动化框架,支持本地私有化运行、多IM平台接入、多模型调度,可完成文档处理、信息检索、流程自动化、智能对话等任务。其轻量化、可扩展、隐私安全的特性,让个人用户与小型团队无需专业开发能力即可搭建专属AI助手。
1555 2
|
机器学习/深度学习 数据采集 PyTorch
使用PyTorch解决多分类问题:构建、训练和评估深度学习模型
使用PyTorch解决多分类问题:构建、训练和评估深度学习模型
使用PyTorch解决多分类问题:构建、训练和评估深度学习模型
|
12月前
|
安全 数据挖掘 大数据
Python数字处理:从基础到进阶的实用指南
Python作为“电池包含”的编程语言,提供了丰富的数字处理功能。本文系统讲解数字类型选择、运算技巧、格式化方法及实战案例,帮助开发者高效处理大数计算、精度控制、科学运算等场景,提升代码性能与可靠性。
309 0
|
7月前
|
人工智能 API 数据库
从AI检索原理到geo优化:技术驱动的GEO监测策略
随着AI搜索兴起,信息获取从关键词匹配转向语义理解。本文深入解析GEO(生成式引擎优化)技术原理,对比SEO与GEO的核心差异,揭示RAG、向量化检索的底层逻辑,并介绍如何通过真实用户行为模拟实现精准监测,助力企业构建面向AI时代的内容优化体系。
1117 0
|
机器学习/深度学习 人工智能 算法
Stable Virtual Camera:2D秒变3D电影!Stability AI黑科技解锁无限运镜,自定义轨迹一键生成
Stable Virtual Camera 是 Stability AI 推出的 AI 模型,能够将 2D 图像转换为具有真实深度和透视感的 3D 视频,支持自定义相机轨迹和多种动态路径,生成高质量且时间平滑的视频。
1155 0
Stable Virtual Camera:2D秒变3D电影!Stability AI黑科技解锁无限运镜,自定义轨迹一键生成
|
JSON 前端开发 开发工具
初探在WSL中设置vim前端开发环境
初探在WSL中设置vim前端开发环境
|
存储 缓存 NoSQL
Redis八股文(大厂面试真题)
Redis八股文(大厂面试真题)
831 1
Redis八股文(大厂面试真题)
|
机器学习/深度学习 人工智能 TensorFlow
基于TensorFlow的深度学习模型训练与优化实战
基于TensorFlow的深度学习模型训练与优化实战
807 3