I'm quite new to signal analysis, and I'm currently trying to understand under which conditions a Hilbert transform can be used to compute the correct instantaneous phase and enveloppe of a given signal.
Say I start from the example in Python given here (from the scipy website):
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
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 = plt.figure()
ax0 = fig.add_subplot(211)
ax0.plot(t, signal, label='signal')
ax0.plot(t, amplitude_envelope, label='envelope')
ax0.set_xlabel("time in seconds")
ax0.legend()
ax1 = fig.add_subplot(212)
ax1.plot(t[1:], instantaneous_frequency)
ax1.set_xlabel("time in seconds")
ax1.set_ylim(0.0, 120.0)
I get a nice result showing me the enveloppe and desired frequency:
However, if for instance I decide to add a little bit of noise:
signal+=random.rand(len(signal))*0.2
Then the inferred enveloppe and frequencies get not that good (some of the noise goes into the enveloppe, some into the frequencies):
This was quite expectable, and I know I just have to find a way to smooth my signal to solve that. My real problem is, say you add a trend to your signal:
signal+=np.linspace(-1,1,400)
Then the results get completely messed up: *can't add any more links since I'm new to the forum*
And the results are also messed up even for just a vertical shift... So, basically, my question is: what are the conditions needed for the Hilbert transform to return the correct phase and amplitude ?
For now, this is what I suppose:
- the signal must not be noisy
- the signal must be centered around zero
- the signal must not have any trend
- amplitude and frequency can vary
Am I right? Thank you.