minimum_phase#
- scipy.signal.minimum_phase(h, method='homomorphic', n_fft=None, *, half=True)[源代码]#
将线性相位 FIR 滤波器转换为最小相位
- 参数:
- h数组
线性相位 FIR 滤波器系数。
- method{‘hilbert’, ‘homomorphic’}
提供的方法有:
- n_fft整型
用于 FFT 的点数。应至少是信号长度的几倍(参见备注)。
- half布尔型
如果为
True
,则创建一个长度为原始滤波器一半、幅度谱为原始滤波器平方根的滤波器。如果为False
,则创建一个与原始滤波器长度相同、幅度谱旨在匹配原始滤波器的滤波器(仅在method='homomorphic'
时支持)。在版本 1.14.0 中新增。
- 返回值:
- h_minimum数组
滤波器的最小相位版本,当
half is True
时长度为(len(h) + 1) // 2
,否则为len(h)
。
备注
希尔伯特[1]和同态[4] [5]方法都需要选择 FFT 长度来估计滤波器的复倒谱。
在使用希尔伯特方法时,与理想谱
epsilon
的偏差与阻带零点数n_stop
和 FFT 长度n_fft
的关系如下:epsilon = 2. * n_stop / n_fft
例如,当阻带零点数为 100 且 FFT 长度为 2048 时,
epsilon = 0.0976
。如果我们保守地假设阻带零点数比滤波器长度少一,我们可以将 FFT 长度取为满足epsilon=0.01
的下一个 2 的幂,如下所示:n_fft = 2 ** int(np.ceil(np.log2(2 * (len(h) - 1) / 0.01)))
这两种方法(希尔伯特和同态)都能获得合理的结果,并且当
n_fft=None
时使用此值。存在其他创建最小相位滤波器的方法,包括零点反演[2]和谱因式分解[3] [4]。欲了解更多信息,请参阅此 DSPGuru 页面。
参考文献
[1] (1,2)N. Damera-Venkata and B. L. Evans, “Optimal design of real and complex minimum phase digital FIR filters,” Acoustics, Speech, and Signal Processing, 1999. Proceedings., 1999 IEEE International Conference on, Phoenix, AZ, 1999, pp. 1145-1148 vol.3. DOI:10.1109/ICASSP.1999.756179
[2]X. Chen and T. W. Parks, “Design of optimal minimum phase FIR filters by direct factorization,” Signal Processing, vol. 10, no. 4, pp. 369-383, Jun. 1986.
[3]T. Saramaki, “Finite Impulse Response Filter Design,” in Handbook for Digital Signal Processing, chapter 4, New York: Wiley-Interscience, 1993.
示例
创建一个最佳线性相位低通滤波器h,其过渡带为 [0.2, 0.3](假设奈奎斯特频率为 1)
>>> import numpy as np >>> 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, fs=2)
将其转换为最小相位
>>> h_hil = minimum_phase(h_linear, method='hilbert') >>> h_hom = minimum_phase(h_linear, method='homomorphic') >>> h_hom_full = minimum_phase(h_linear, method='homomorphic', half=False)
比较这四个滤波器的脉冲响应和频率响应
>>> fig0, ax0 = plt.subplots(figsize=(6, 3), tight_layout=True) >>> fig1, axs = plt.subplots(3, sharex='all', figsize=(6, 6), tight_layout=True) >>> ax0.set_title("Impulse response") >>> ax0.set(xlabel='Samples', ylabel='Amplitude', xlim=(0, len(h_linear) - 1)) >>> axs[0].set_title("Frequency Response") >>> axs[0].set(xlim=(0, .65), ylabel="Magnitude / dB") >>> axs[1].set(ylabel="Phase / rad") >>> axs[2].set(ylabel="Group Delay / samples", ylim=(-31, 81), ... xlabel='Normalized Frequency (Nyqist frequency: 1)') >>> for h, lb in ((h_linear, f'Linear ({len(h_linear)})'), ... (h_hil, f'Min-Hilbert ({len(h_hil)})'), ... (h_hom, f'Min-Homomorphic ({len(h_hom)})'), ... (h_hom_full, f'Min-Homom. Full ({len(h_hom_full)})')): ... w_H, H = freqz(h, fs=2) ... w_gd, gd = group_delay((h, 1), fs=2) ... ... alpha = 1.0 if lb == 'linear' else 0.5 # full opacity for 'linear' line ... ax0.plot(h, '.-', alpha=alpha, label=lb) ... axs[0].plot(w_H, 20 * np.log10(np.abs(H)), alpha=alpha) ... axs[1].plot(w_H, np.unwrap(np.angle(H)), alpha=alpha, label=lb) ... axs[2].plot(w_gd, gd, alpha=alpha) >>> ax0.grid(True) >>> ax0.legend(title='Filter Phase (Order)') >>> axs[1].legend(title='Filter Phase (Order)', loc='lower right') >>> for ax_ in axs: # shade transition band: ... ax_.axvspan(freq[1], freq[2], color='y', alpha=.25) ... ax_.grid(True) >>> plt.show()
脉冲响应和群延迟图描绘了线性相位滤波器h的 75 个采样延迟。由于幅度很小,阻带中的相位也应是线性的,但在该区域数字噪声占主导。此外,这些图显示最小相位滤波器在通带和过渡带中明显显示出减小的(负)相位斜率。这些图还说明,参数为
method='homomorphic', half=False
的滤波器与线性滤波器h具有相同的阶数和幅度响应,而其他最小相位滤波器只有一半的阶数和幅度响应的平方根。