scipy.signal.

hilbert#

scipy.signal.hilbert(x, N=None, axis=-1)[源代码]#

基于 FFT 的解析信号计算。

解析信号是通过在 FFT 域中滤除负频率并将正频率的幅度加倍来计算的。结果的虚部是实值输入信号的希尔伯特变换。

默认情况下,变换是沿最后一个轴进行的。

参数:
x类数组

信号数据。必须是实数。

Nint, 可选

傅里叶分量数量。默认值:x.shape[axis]

axisint, 可选

进行变换的轴。默认值:-1。

返回:
xandarray

x 的解析信号,针对沿 axis 的每个一维数组。

另请参阅

envelope

计算实值或复值信号的包络。

说明

实值信号 x(t) 的解析信号 x_a(t) 可以表示为 [1]

\[x_a = F^{-1}(F(x) 2U) = x + i y\ ,\]

其中 F 是傅里叶变换,U 是单位阶跃函数,而 yx 的希尔伯特变换。 [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()
../../_images/scipy-signal-hilbert-1.png