为什么 Hilbert() 函数的 Scipy 实现与函数的 Matlab 实现不同?

信息处理 matlab 希尔伯特变换 scipy 超声波
2022-01-01 15:03:25

我正在尝试将希尔伯特包络拟合到频率为 250 KHZ 且采样率为 12000000 的高频超声波信号。原始信号如下所示:原始信号

我在 python 中使用了 scipy.signal 包中的 hilbert() 函数,这就是它的样子希尔伯特变换

python代码如下所示

from scipy.signal import hilbert
import numpy as np
 def Hilbert(self,i=0):
    analytical_signal = hilbert(self.sensor["s"+str(i)])
    amplitude_envelope = np.abs(analytical_signal)
    return amplitude_envelope

Matlab 实现看起来像这样Matlab实现

Matlab代码如下:

figure;
plot(abs(hilbert(signal)),'r');
hold on; 
plot(signal,'b');

线路数据如下Signal我想知道哪个是正确的?

4个回答

这对我来说可以:

from scipy.signal import hilbert
import numpy as np
from matplotlib.pyplot import plot

sensor = np.loadtxt('signal.txt')
plot(sensor)

analytical_signal = hilbert(sensor)
plot(analytical_signal.real)
plot(analytical_signal.imag)

amplitude_envelope = np.abs(analytical_signal)
plot(amplitude_envelope)

在此处输入图像描述

在此处输入图像描述

你在做什么不同的事情?也许您正在以某种方式丢弃虚构的部分analytical_signal

你必须消除信号的趋势。如果您有 DC 组件,则行为会完全改变。

dt=0.0001
t = np.arange(0,0.1,dt)
x = (1+np.cos(2*np.pi*50*t))*np.cos(2*np.pi*1000*t)
plt.plot(x)

在此处输入图像描述

h=abs(hilbert(x))    
plt.plot(h)

在此处输入图像描述

x=x+1
h=abs(hilbert(x))
plt.plot(h)

在此处输入图像描述

这是因为 hilbert(x) 返回 de 解析函数 xr(t)+jxh(t),其中 xh 是 Hilbert 变换,xr 是原始信号 x(t)。x(t) 的 xh 与 x'=x(t)+k 的 xh 相同(希尔伯特对常数的变换为零)。因此,当您将包络计算为 abs(hilbert(xr)) 时,您会得到 sqrt(xr^2+xh^2)。如果你使用 x'=x(t)+k,你会得到 sqrt((xr+k)^2+xh^2)。

在 Matlab 中,envelope() 函数在应用 hibert() 之前减去平均值。如果你使用 abs(hilbert()) 你应该得到与 Python 相同的结果。

PD:写完之后,我下载了你的信号,并在上面测试了 abs(hilbert())。在 Python 中,我获得了信封......

在此处输入图像描述

我遇到过同样的问题。正如 https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.hilbert.html 所说@Notes,您需要获取希尔伯特变换结果的虚部......“希尔伯特转换后的信号可以从 np.imag(hilbert(x)) 获得,原始信号可以从 np.real(hilbert(x)) 获得。"

我不知道蟒蛇。但理论上,

希尔伯特变换通过以下方式完成:

  1. 信号的实部
  2. 将信号相位旋转 90°
  3. 分析信号 = 实数 + i*(旋转信号)。
  4. 包络是一个距离函数。它是分析信号中心与样本幅度之间的距离。
  5. 瞬时频率是角度。

所以,我从图中猜想你忘记考虑信号的虚部。这就是为什么您看不到包络而是看到真实信号的绝对值的原因。