scipy.signal.

希尔伯特#

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

计算解析信号,使用希尔伯特变换。

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

参数:
xarray_like

信号数据。必须是实数。

Nint, 可选

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

int, 可选

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

返回:
xandarray

沿 axis 的每个一维数组的 x 的解析信号

注释

信号 x(t) 的解析信号 x_a(t) 是:

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

其中 F 是傅里叶变换,U 是单位阶跃函数,yx 的希尔伯特变换。 [1]

换句话说,频率谱的负半部分被置零,将实值信号转换为复信号。Hilbert变换后的信号可以通过 np.imag(hilbert(x)) 获得,原始信号可以通过 np.real(hilbert(x)) 获得。

参考文献

[1]

维基百科,“解析信号”。https://en.wikipedia.org/wiki/Analytic_signal

[2]

Leon Cohen, “时频分析”, 1995. 第二章。

[3]

Alan V. Oppenheim, Ronald W. Schafer. 离散时间信号处理,第三版,2009年。第12章。ISBN 13: 978-1292-02572-8

示例

在这个例子中,我们使用希尔伯特变换来确定一个调幅信号的幅度包络和瞬时频率。

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy.signal import hilbert, chirp
>>> duration = 1.0
>>> fs = 400.0
>>> samples = int(fs*duration)
>>> t = np.arange(samples) / fs

我们创建一个频率从20 Hz增加到100 Hz的啁啾信号,并应用幅度调制。

>>> 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)
>>> ax0.plot(t, signal, label='signal')
>>> ax0.plot(t, amplitude_envelope, label='envelope')
>>> ax0.set_xlabel("time in seconds")
>>> ax0.legend()
>>> ax1.plot(t[1:], instantaneous_frequency)
>>> ax1.set_xlabel("time in seconds")
>>> ax1.set_ylim(0.0, 120.0)
>>> fig.tight_layout()
../../_images/scipy-signal-hilbert-1.png