scipy.signal.
hilbert#
- scipy.signal.hilbert(x, N=None, axis=-1)[源代码]#
基于 FFT 的解析信号计算。
解析信号通过滤除负频率并在 FFT 域中将正频率的幅度加倍来计算。结果的虚部是实值输入信号的希尔伯特变换。
默认情况下,变换是沿着最后一个轴进行的。
- 参数:
- xarray_like
信号数据。必须是实数。
- Nint, 可选
傅立叶分量的数量。默认值:
x.shape[axis]
- axisint, 可选
进行变换的轴。默认值:-1。
- 返回:
- xandarray
x 的解析信号,沿着 axis 的每个 1 维数组
另请参阅
envelope
计算实值或复值信号的包络。
注释
实值信号
x(t)
的解析信号x_a(t)
可以表示为 [1]\[x_a = F^{-1}(F(x) 2U) = x + i y\ ,\]其中 F 是傅立叶变换,U 是单位阶跃函数,y 是 x 的希尔伯特变换。[2]
换句话说,频率频谱的负半部分被置零,将实值信号转换为复值信号。希尔伯特变换后的信号可以从
np.imag(hilbert(x))
获得,原始信号可以从np.real(hilbert(x))
获得。参考文献
[1]维基百科,“解析信号”。 https://en.wikipedia.org/wiki/Analytic_signal
[2]维基百科,“希尔伯特变换”。 https://en.wikipedia.org/wiki/Hilbert_transform
[3]Leon Cohen,“时频分析”,1995 年。第 2 章。
[4]Alan V. Oppenheim,Ronald W. Schafer。“离散时间信号处理”,第三版,2009 年。第 12 章。ISBN 13:978-1292-02572-8
示例
在这个例子中,我们使用希尔伯特变换来确定幅度调制信号的幅度包络和瞬时频率。
让我们创建一个频率从 20 Hz 增加到 100 Hz 的线性调频信号,并应用幅度调制
>>> import numpy as np >>> import matplotlib.pyplot as plt >>> from scipy.signal import hilbert, chirp ... >>> duration, fs = 1, 400 # 1 s signal with sampling frequency of 400 Hz >>> t = np.arange(int(fs*duration)) / fs # timestamps of samples >>> signal = chirp(t, 20.0, t[-1], 100.0) >>> signal *= (1.0 + 0.5 * np.sin(2.0*np.pi*3.0*t) )
幅度包络由解析信号的幅度给出。瞬时频率可以通过对瞬时相位关于时间求导获得。瞬时相位对应于解析信号的相位角。
>>> analytic_signal = hilbert(signal) >>> amplitude_envelope = np.abs(analytic_signal) >>> instantaneous_phase = np.unwrap(np.angle(analytic_signal)) >>> instantaneous_frequency = np.diff(instantaneous_phase) / (2.0*np.pi) * fs ... >>> fig, (ax0, ax1) = plt.subplots(nrows=2, sharex='all', tight_layout=True) >>> ax0.set_title("Amplitude-modulated Chirp Signal") >>> ax0.set_ylabel("Amplitude") >>> ax0.plot(t, signal, label='Signal') >>> ax0.plot(t, amplitude_envelope, label='Envelope') >>> ax0.legend() >>> ax1.set(xlabel="Time in seconds", ylabel="Phase in rad", ylim=(0, 120)) >>> ax1.plot(t[1:], instantaneous_frequency, 'C2-', label='Instantaneous Phase') >>> ax1.legend() >>> plt.show()