📌 目录

  1. scipy.signal 模块简介
  2. 卷积与相关运算:convolvecorrelate
  3. 滤波器设计与应用
  4. 快速傅里叶变换(FFT)
  5. 峰值检测:find_peaks
  6. 示例:滤波降噪与峰值检测
  7. 示例:音频信号的频谱分析
  8. 出站链接与参考资料

1. scipy.signal 模块简介

scipy.signal 是 SciPy 中用于一维和二维信号处理的模块,提供:

  • 滤波器设计与应用(IIR/FIR)
  • 卷积、相关运算
  • 快速傅里叶变换(FFT)
  • 峰值检测、脉冲响应
  • 滤波器特性图形绘制

适用于语音识别、图像分析、医学信号等场景。


2. 卷积与相关运算

卷积:scipy.signal.convolve

计算两个信号之间的卷积,模拟线性系统响应。

from scipy.signal import convolve
import numpy as np

a = np.array([1, 2, 3])
b = np.array([0, 1, 0.5])

y = convolve(a, b, mode='full')
print("卷积结果:", y)

相关:scipy.signal.correlate

用于检测两个信号之间的相似性(如延迟估计)。

from scipy.signal import correlate

corr = correlate(a, b, mode='full')
print("相关结果:", corr)


3. 滤波器设计与应用

巴特沃斯低通滤波器设计与使用

from scipy.signal import butter, filtfilt

# 创建低通滤波器(截止频率 0.2)
b, a = butter(N=4, Wn=0.2, btype='low')
filtered = filtfilt(b, a, np.random.randn(100))

print("滤波后信号:", filtered)

FIR 滤波器设计

from scipy.signal import firwin

taps = firwin(numtaps=29, cutoff=0.3)


4. 快速傅里叶变换(FFT)

from scipy.fft import fft, fftfreq
import matplotlib.pyplot as plt

# 构造正弦信号
fs = 1000  # 采样频率
t = np.linspace(0, 1, fs, endpoint=False)
x = np.sin(2*np.pi*50*t) + 0.5*np.sin(2*np.pi*120*t)

# FFT
y = fft(x)
f = fftfreq(len(x), 1/fs)

plt.plot(f[:500], np.abs(y[:500]))
plt.title("频谱")
plt.xlabel("频率 (Hz)")
plt.ylabel("幅度")
plt.grid()
plt.show()


5. 峰值检测:find_peaks

from scipy.signal import find_peaks

x = np.array([0, 1, 0, 2, 0, 3, 0])
peaks, _ = find_peaks(x, height=1)
print("峰值索引:", peaks)

用于生物信号(如心电图)峰值检测等。


6. 示例:滤波降噪与峰值检测

# 模拟信号 + 噪声
signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.random.randn(len(t))

# 滤波器
b, a = butter(N=6, Wn=0.1)
filtered_signal = filtfilt(b, a, signal)

# 峰值检测
peaks, _ = find_peaks(filtered_signal, height=0.3)

plt.plot(t, signal, label='原始')
plt.plot(t, filtered_signal, label='滤波后')
plt.plot(t[peaks], filtered_signal[peaks], "rx", label="峰值")
plt.legend()
plt.title("信号降噪与峰值检测")
plt.show()


7. 示例:音频信号频谱分析

import soundfile as sf

data, samplerate = sf.read('example.wav')  # 需要安装 soundfile 库
y = fft(data)
f = fftfreq(len(data), 1/samplerate)

plt.plot(f[:10000], np.abs(y[:10000]))
plt.title("音频频谱")
plt.xlabel("频率 (Hz)")
plt.ylabel("强度")
plt.grid()
plt.show()


🔗 出站链接与参考资料

📘 官方文档

🎓 教程与实战