 # Obtain Envelope

Hello,

is there any function or library to obtain the envelope of a signal ?

Thank you all.

1 Like

You can do it using a Hilbert transform, like so:

``````using DSP, Plots
x = 0:0.1:200
y = sin.(x) .+ sin.(1.2x)
env = abs.(hilbert(y))
plot(x, y)
plot!(x, env)
plot!(x, -env)
`````` 6 Likes

line 4 should be `env = abs.(hilbert(y))`

Could you give an example of what your signal source is? Depending on the field, “envelope” is not always a completely defined concept. For example, EMG signals commonly include tall and narrow peaks that would unduly distort an envelope calculated with the Hilbert transform method above. The most common method of obtaining the envelope for EMG signals is to full-wave rectify (ie `abs(x)`) and low pass filter.

2 Likes

Thanks, updated!

2 Likes

Crystal radio to the rescue! My tech roots lie in shortwave and ham radio many many years ago and it’s neat when those basics come up in other contexts.

Thank you all for your input!

I work with signals from vibrating structures. Sometimes the signals are smooth and sometimes are non-smooth. They look quite similar to the plot in the link below: For this kind of signals , I think the approach mentioned by @ElOceanografo seems adequate. Is it apt also for signals non-symmetric respect to the time axis?

1 Like

I believe that the discrete Hilbert envelope technique used here may assume continuous, band-limited (non-aliased), periodic signals. One may want to taper the beginning and end of the signal to avoid a possible discontinuity there (from the assumed periodicity).

2 Likes

One example of the Hilbert envelope of a signal which is not periodic, not band-limited and not continuous:

``````using DSP, Plots
x = collect(-20:0.1:27)
y = [[-cos(u) for u in x if u<0]; 2*[cos(u)+cos(1.2u) for u in x if u>=0]];
env = abs.(hilbert(y))
plot(x, y)
plot!(x, env)
plot!(x, -env)
``````
2 Likes

Neat example. If your application lets you ignore those transients (maybe you know a priori where they will be) it does pretty well.

2 Likes

An alternative approach to compute the envelope from local extremes using the functions findlocalmaxima() and findlocalminima() available in Images.jl package:

``````using Images, Plots
x = collect(-20:0.1:27)
y = [[-cos(u) for u in x if u<0]; 2*[cos(u)+cos(1.2u) for u in x if u>=0]];
maxy_ix = findlocalmaxima(y)
miny_ix = findlocalminima(y)
plot(x, y)
plot!(x[maxy_ix],y[maxy_ix])
plot!(x[miny_ix],y[miny_ix])
``````
3 Likes