Reputation: 383
I am trying to compute the envelope of a signal using the Hilbert transform in Scipy. Here is the code,
import numpy as np
from scipy.signal import hilbert
A=2
lamb=20
w=2*np.pi*100
signal = A**(-lamb*t)*(np.sin(w*t+5)+np.cos(w*t+5))
analytic_signal = hilbert(signal)
amplitude_envelope = np.abs(analytic_signal)
if one plots the signal and the envelope, the latter show quite high values both at the beginning and at the end... see figure attached. Any tips on how to fix this issue and get a better envelope?
Upvotes: 2
Views: 2881
Reputation: 114831
A basic assumption of hilbert
is that the input signal is periodic. If you extended your signal to be periodic, then at t=1 there would be a big jump from the long, flat tail to the repetition of the initial burst of the signal.
One way to handle this is to apply hilbert
to an even extension of the signal, such as the concatenation of the signal with a reversed copy of itself, e.g. np.concatenate((signal[::-1], signal))
. Here's a modified version of your script that does this:
import numpy as np
from scipy.signal import hilbert
import matplotlib.pyplot as plt
A = 2
lamb = 20
w = 2*np.pi*100
fs = 8000
T = 1.0
t = np.arange(int(fs*T)) / fs
signal = A**(-lamb*t)*(np.sin(w*t+5)+np.cos(w*t+5))
# Make an even extension of `signal`.
signal2 = np.concatenate((signal[::-1], signal))
analytic_signal2 = hilbert(signal2)
# Get the amplitude of the second half of analytic_signal2
amplitude_envelope = np.abs(analytic_signal2[len(t):])
plt.plot(t, signal, label='signal')
plt.plot(t, amplitude_envelope, label='envelope')
plt.xlabel('t')
plt.legend(framealpha=1, shadow=True)
plt.grid()
plt.show()
Here's the plot that is created by the script:
Upvotes: 2