- sos滤波器是什么
- 为什么要 zpk2sos
- 如何实现零相位滤波,优缺点分别是什么
滤波器的计算流程
滤波器的计算设计流程:
1.输入验证和处理:
2.检查频率范围是否合法,计算归一化的频率。
3.滤波器设计:设计带通 Butterworth 滤波器并转换为 SOS 表示。
4.滤波应用:根据 zerophase 参数决定是否进行双向滤波(正向 + 反向)或仅进行正向滤波。
5.返回结果:返回处理后的滤波数据。
def bandpass(data, freqmin, freqmax, df, corners=4, zerophase=False):
"""
Butterworth-Bandpass Filter.
Filter data from ``freqmin`` to ``freqmax`` using ``corners``
corners.
The filter uses :func:`scipy.signal.iirfilter` (for design)
and :func:`scipy.signal.sosfilt` (for applying the filter).
:type data: numpy.ndarray
:param data: Data to filter.
:param freqmin: Pass band low corner frequency.
:param freqmax: Pass band high corner frequency.
:param df: Sampling rate in Hz.
:param corners: Filter corners / order.
:param zerophase: If True, apply filter once forwards and once backwards.
This results in twice the filter order but zero phase shift in
the resulting filtered trace.
:return: Filtered data.
"""
fe = 0.5 * df
low = freqmin / fe
high = freqmax / fe
# raise for some bad scenarios
if high - 1.0 > -1e-6:
msg = ("Selected high corner frequency ({}) of bandpass is at or "
"above Nyquist ({}). Applying a high-pass instead.").format(
freqmax, fe)
warnings.warn(msg)
return highpass(data, freq=freqmin, df=df, corners=corners,
zerophase=zerophase)
if low > 1:
msg = "Selected low corner frequency is above Nyquist."
raise ValueError(msg)
z, p, k = iirfilter(corners, [low, high], btype='band',
ftype='butter', output='zpk')
sos = zpk2sos(z, p, k)
if zerophase:
firstpass = sosfilt(sos, data)
return sosfilt(sos, firstpass[::-1])[::-1]
else:
return sosfilt(sos, data)
sos 滤波器是什么
零相位滤波器
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
# 生成示例数据:一个带有噪声的正弦信号
fs = 1000 # 采样频率(Hz)
t = np.linspace(0, 1, fs) # 时间向量
freq1 = 5 # 低频
freq2 = 50 # 高频
signal_clean = np.sin(2 * np.pi * freq1 * t) + np.sin(2 * np.pi * freq2 * t) # 清晰信号
noise = np.random.randn(len(t)) * 0.2 # 噪声
signal_noisy = signal_clean + noise # 带噪声的信号
# 设计带通滤波器
lowcut = 10 # 带通滤波器的低频边界(Hz)
highcut = 40 # 带通滤波器的高频边界(Hz)
# 使用巴特沃斯滤波器设计
b, a = signal.butter(4, [lowcut, highcut], fs=fs, btype='band')
# 使用 filtfilt 进行零相位滤波
signal_filtered = signal.filtfilt(b, a, signal_noisy)
# 绘制结果
plt.figure(figsize=(10, 6))
plt.subplot(3, 1, 1)
plt.plot(t, signal_noisy, label="Noisy signal")
plt.title("Noisy Signal")
plt.subplot(3, 1, 2)
plt.plot(t, signal_clean, label="Original Clean Signal", color='g')
plt.title("Original Clean Signal")
plt.subplot(3, 1, 3)
plt.plot(t, signal_filtered, label="Filtered Signal", color='r')
plt.title("Filtered Signal with Zero-Phase")
plt.tight_layout()
plt.show()