我正在尝试将一些 MATLAB 代码移植到 Python 并遇到一些奇怪的行为。我正在实现一个 5 阶巴特沃斯带通滤波器。采样率为 30 Hz。
在 Windows 7 x64 上运行 MATLAB R2012b、Spyder 2.2.0 和 Python 2.7、SciPy 0.12.0。
在 MATLAB 中:
[b,a] = butter(5, [0.75*2/30, 5.0*2/30], 'bandpass');
y = filtfilt(b, a, input_signal)
这是原始信号:
和滤波后的信号:
及其功率谱:
这是有道理的,因为归一化的带通频率是 0.05 - 0.33。
我之前发现 SciPy 的 butter 函数没有给出与 MATLAB 相同的系数,所以我使用 hdf5write 将滤波器系数从 MATLAB 导出到 Python(参见此处:https ://stackoverflow.com/questions/7117797/export-matlab-variable-to -text-for-python-usage )
在 Python 中:
y = signal.filtfilt(b, a, input_signal, padtype = None)
输出是:
及其功率谱:
我使用了 padtype = None,因为默认情况下它是 padtype = 'odd'。但是,我尝试了所有不同的填充选项,它们看起来都差不多。
我不完全确定出了什么问题......任何帮助将不胜感激。
编辑:添加了 padtype = "odd" 和 b 的图形以及使用的滤波器系数
padtype = "odd" 的信号:
似乎有一些潜在的信号,所以我不认为这是脉冲响应,尽管一开始的大瞬态很奇怪。
Python 滤波器系数(5 阶巴特沃斯滤波器):
passband = [0.75*2/30, 5.0*2/30]
b, a = scipy.signal.butter(5, passband, 'bandpass')
b, a 是 float64 类型的数组。
b = array([ 5.49209388e-03, 0.00000000e+00, -2.74604694e-02,
-1.97776791e-17, 5.49209388e-02, 2.47220989e-17,
-5.49209388e-02, -1.97776791e-17, 2.74604694e-02,
0.00000000e+00, -5.49209388e-03])
a = array([ 1. , -6.52098852, 19.50384534, -35.47189804,
43.65758795, -38.07760914, 23.83047021, -10.55670367,
3.16710078, -0.58122912, 0.04945954])
MATLAB 滤波器系数
b = 0.0055, 0, -0.0275, 0, 0.0549, 0, -0.0549, 0, 0.0275, 0, -0.0055
a = 1.0000, -6.5210, 19.5038, -35.4719, 43.6576, -38.0776, 23.8305,
-10.5567, 3.1671, -0.5812, 0.0495
结果系数大致相同,我相信我之前遇到的问题是由于频率要高得多(在 MATLAB 和 Python 中必须以不同的方式生成系数)。
输入信号是一个 float32 列表,尽管我尝试使用 numpy.array 转换为数组,结果是一样的。
编辑:有关 padtypes 和 Python 与 MATLAB 的更多信息
Python SciPy 的 filtfilt 函数包括一个名为 padtype 的参数,它指示在信号两侧扩展的填充类型。该填充用于减少瞬变。奇数和偶数是这些扩展与端点的对称类型的描述符(http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.filtfilt.html)。
padtypes差异的一些插图:
padtype =“偶数”
padtype =“奇数”
padtype = 无
根据结果,MATLAB 似乎使用了奇数填充(这也是 Python 的默认值):