scipy.signal.minimum_phase¶
- scipy.signal.minimum_phase(h, method='homomorphic', n_fft=None)[源代码]¶
将线性相位FIR过滤转换为最小相位
- 参数
- h阵列
线性相位FIR过滤系数。
- method{‘希尔伯特’,‘同态’}
要使用的方法:
- n_fft集成
用于FFT的点数。应至少比信号长度大几倍(参见注释)。
- 退货
- h_minimum阵列
过滤的最小相位版本,长度
(length(h) + 1) // 2
。
注意事项
希尔伯特夫妇 [1] 或同态的 [4] [5] 这些方法需要选择快速傅立叶变换的长度来估计过滤的复倒频谱。
在希尔伯特方法的情况下,与理想谱的偏差
epsilon
与阻带零点的数目有关n_stop
和FFT长度n_fft
AS::epsilon = 2. * n_stop / n_fft
例如,利用100个阻带零和2048的FFT长度,
epsilon = 0.0976
。如果我们保守地假设阻带零的数目比过滤长度小1,我们可以将fft长度取为满足条件的2的下一个幂epsilon=0.01
AS::n_fft = 2 ** int(np.ceil(np.log2(2 * (len(h) - 1) / 0.01)))
这给出了希尔伯特方法和同态方法的合理结果,并给出了在以下情况下使用的值
n_fft=None
。存在用于创建最小相位滤波器的替代实现,包括零反转 [2] 和谱因式分解 [3] [4] 。有关详细信息,请参阅:
参考文献
- 1(1,2)
N.Damera-Venkata和B.L.Evans,“实数和复数最小相位数字FIR滤波器的优化设计”,“声学、语音和信号处理”,1999。论文集,1999年IEEE国际会议,凤凰城,亚利桑那州,1999年,第1145-1148页,第3卷。 DOI:10.1109/ICASSP.1999.756179
- 2
陈锡文和T.W.Parks,“基于直接因式分解的最优最小相位FIR滤波器的设计”,“信号处理”,第一卷。1986年6月,第10期,第4期,第369-383页。
- 3
萨拉马基,“有限脉冲响应过滤设计”,“数字信号处理手册”,第4章,纽约:威利国际科学出版社,1993年。
- 4(1,2,3)
林俊生,信号处理高级专题。恩格尔伍德·克里夫斯,新泽西州:普伦蒂斯·霍尔出版社,1988。
- 5(1,2)
A.V.Oppenheim,R.W.Schafer和J.R.Buck,“离散时间信号处理”,第2版。马鞍河上游,新泽西州:Prentice Hall,1999。
示例
创建最佳线性相位过滤,然后将其转换为最小相位:
>>> from scipy.signal import remez, minimum_phase, freqz, group_delay >>> import matplotlib.pyplot as plt >>> freq = [0, 0.2, 0.3, 1.0] >>> desired = [1, 0] >>> h_linear = remez(151, freq, desired, Hz=2.)
将其转换为最小相位:
>>> h_min_hom = minimum_phase(h_linear, method='homomorphic') >>> h_min_hil = minimum_phase(h_linear, method='hilbert')
比较这三个筛选器:
>>> fig, axs = plt.subplots(4, figsize=(4, 8)) >>> for h, style, color in zip((h_linear, h_min_hom, h_min_hil), ... ('-', '-', '--'), ('k', 'r', 'c')): ... w, H = freqz(h) ... w, gd = group_delay((h, 1)) ... w /= np.pi ... axs[0].plot(h, color=color, linestyle=style) ... axs[1].plot(w, np.abs(H), color=color, linestyle=style) ... axs[2].plot(w, 20 * np.log10(np.abs(H)), color=color, linestyle=style) ... axs[3].plot(w, gd, color=color, linestyle=style) >>> for ax in axs: ... ax.grid(True, color='0.5') ... ax.fill_between(freq[1:3], *ax.get_ylim(), color='#ffeeaa', zorder=1) >>> axs[0].set(xlim=[0, len(h_linear) - 1], ylabel='Amplitude', xlabel='Samples') >>> axs[1].legend(['Linear', 'Min-Hom', 'Min-Hil'], title='Phase') >>> for ax, ylim in zip(axs[1:], ([0, 1.1], [-150, 10], [-60, 60])): ... ax.set(xlim=[0, 1], ylim=ylim, xlabel='Frequency') >>> axs[1].set(ylabel='Magnitude') >>> axs[2].set(ylabel='Magnitude (dB)') >>> axs[3].set(ylabel='Group delay') >>> plt.tight_layout()