带有滑动窗口的希尔伯特变换
信息处理
过滤器
阶段
希尔伯特变换
窗户
2022-02-14 18:41:56
2个回答
也许包括一些包含最小工作示例的代码会有所帮助。我没有看到任何问题。
我尝试这样做是因为我对相关问题感兴趣并且最近了解了希尔伯特变换。我还添加了一些噪音,因为噪音总是存在的,但在回答这样的问题时经常被忽略(我的一个小毛病),即使它有时会完全击败某些方法。这是我得到的:
import numpy as np
import scipy.signal as sig
import matplotlib.pyplot as plt
# Parameters
N = 1300
t = np.arange(0,N)
f = 1.0/20
# Discontinuous amplitude envelope
A = np.ones(t.size)
A[1*t.size/5:2*t.size/5] = .2
# Time signal with noise
y = A*np.sin(2*np.pi*f*t)
y += (np.random.rand(N)*2-1)*.2
# Filter noise
filt = True
if filt :
cutoff = int(N*f*1.5)
yrms1 = (y**2).mean()**.5
yF = np.fft.fft(y)
yF[cutoff:]=0 # Filter
y = np.real(np.fft.ifft(yF))
yrms2 = (y**2).mean()**.5 # Keep signal energy
y *= yrms1/yrms2
# Calculate envelope
envelope = np.abs(sig.hilbert(y));
# Plots
plt.figure(1, figsize=[10,7], dpi=100)
plt.clf()
plt.plot(A, label='Actual envelope')
plt.plot(y, label='Time signal')
plt.plot(envelope, '.', label='Calculated envelope')
plt.legend(loc='lower right')
plt.show()
plt.draw()
plt.pause(.1)
编辑:
在滑动窗口中演示性能。只需将此代码替换为上面包络计算的行。请注意,每个位置的包络线仅使用N_win
周围点计算。
envelope = np.ones(N)*np.nan
N_win = 50 # needs at least twice the period or so
lag = 20 # needs to be >= period.
for i in range(N-N_win) :
envelope[N_win+i-lag] = np.abs(sig.hilbert(y[i:i+N_win]))[-lag]
请注意,为了使我的实现能够正常工作,您需要提前大约 1 个周期来计算信封的位置。对于实时处理,这意味着您的“包络”信号必须落后于主信号至少一个周期。这是因为希尔伯特变换的边缘效应。我不认为真的有任何办法解决这个问题。
我认为这个问题更多地与窗口中的信号不是单调的事实有关,而不是与窗口本身的长度有关。
你看,希尔伯特-黄变换包括在应用希尔伯特变换之前提取信号的 IMF(本征模式函数)。IMF 是各种尺度的信号的单调版本。
您可以看到 Hilbert 输出中的瞬态出现在频率未明确定义的时刻(原始信号中的瞬态)。之前先看看 EMD(经验模式分解)和 Hilbert-Huang 变换,我认为您可能有更好更快的方法来做您想做的事情。
干杯。
其它你可能感兴趣的问题