Amplitude increase after filter

24 vues (au cours des 30 derniers jours)
Kcire L
Kcire L le 11 Mar 2021
Commenté : Star Strider le 11 Mar 2021
Hello,
I am using a moving average to filter and find the envelope of a raw signal. I am curious as to why the amplitude of the filtered envelope is so much higher than the original signal. Does anyone have a way to filter noise out of a signal, while keeping the integrity of the signal as close as possible?
My steps below, along with a screenshot of the raw and filtered envelope.
Thanks for any help
WindowEnvelope = .75;
step1 = abs(signal)/2; % take the absolute value of the signal
step2 = hilbert(step1); % take the hilbert transform of the absolute value
step3 = sqrt(step2.*conj(step2)); % take the sqrt of the complex conjugate of the hilbert transform
step4 = filtfilt(ones(1,round(Fs*WindowEnvelope))/round(Fs*.1),1,step3); %filter the signal
subplot(2,1,1)
plot(t, signal)
subplot(2,1,2)
plot(t, step4)

Réponse acceptée

Star Strider
Star Strider le 11 Mar 2021
If you want the filter (in this instance what appears to be a moving-average filter) not to amplify the signal, the denominator of the transfer function has to equal the sum of the numerator, for example:
step4 = filtfilt(ones(1,round(Fs*WindowEnvelope))/round(Fs*.1), sum(ones(1,round(Fs*WindowEnvelope))/round(Fs*.1)), step3); %filter the signal
would probably work.
  1 commentaire
Star Strider
Star Strider le 11 Mar 2021
It shouldn’t be off at all — that is, it shouldn’t be amplifying.
If you want to see what it’s actually doing (since you have the Signal Processing Toolbox) try this:
figure
freqz(ones(1,round(Fs*WindowEnvelope))/round(Fs*.1) , sum(ones(1,round(Fs*WindowEnvelope))/round(Fs*.1)), 2^16, Fs)
That will display the filter Bode plot, so you can determine if it’s designed correctly.
If you’re simply filtering out high-frequency noise, use the lowpass function instead of the moving-average filter.

Connectez-vous pour commenter.

Plus de réponses (4)

Kcire L
Kcire L le 11 Mar 2021
Now it is off by about a factor of 10, but is it safe to assume that is the normal reduction from the filtering?
step4 = filtfilt(ones(1,round(Fs*WindowEnvelope))/round(Fs*.1),sum(ones(1,round(Fs*WindowEnvelope))/round(Fs*.1)), step3);

Kcire L
Kcire L le 11 Mar 2021
It isn't amplifying anymore but it is now reduced reduced amplitude.
You say it shouldn't be off at all, but doesn't a filter or moving average result in a reduction of amplitude?
Here is the bode.
  4 commentaires
Kcire L
Kcire L le 11 Mar 2021
Would you recommend a low pass filter design 0-100Hz passband that does not attenuate the signal like this?
Thanks again.
Star Strider
Star Strider le 11 Mar 2021
As always, my pleasure!
I would use the Signal Analyzer App, or calculate the fft of the signal, in order to determine its spectral characteristics, then let that information guide the filter design. A lowpass filter with a 100 Hz cutoff may well do what you want it to do. It is likely better than the moving-average filter, and much more predictable.
Filter design and implementation is straightforward in MATLAB. I will help you with that if necessary.

Connectez-vous pour commenter.


Kcire L
Kcire L le 11 Mar 2021
I appreciate your assistance.. Unfortunately I don't have access to MATLAB until late next week and am currently using GNU Octave which does not have the Signal Analyzer App. I've tried code like the following, but it has not produced the results I am expecting.
%% ------------ LP Filter ----------------------
N = 3; % Number of Poles
cutoff = 100; % Cutoff Freqency
wc = cutoff*(2*pi)/(2*pi*Fs);
[b, a] = butter(N, wc, 'low');
raw = filtfilt(b,a,raw);
  1 commentaire
Star Strider
Star Strider le 11 Mar 2021
As always, my pleasure!
Assuming your sampling frequency is 20000 Hz (from the freqz output earlier):
Fs = 2E4;
Fn = Fs/2;
cutoff = 100;
[n,Wn] = buttord(cutoff/Fn, 1.1*cutoff/Fn, 1, 50);
[z,p,k] = butter(n,Wn);
[sos,g] = zp2sos(z,p,k);
figure
freqz(sos, 2^14, Fs)
set(subplot(2,1,1), 'XLim',[0 500]) % Optional
set(subplot(2,1,2), 'XLim',[0 500]) % Optional
That should do what you want. (I have no idea what Octave has available, so I can only hope this works in Octave.)
Also, MATLAB Online might be an option. I have not used it, since I always have my desktop or a laptop available.

Connectez-vous pour commenter.


Kcire L
Kcire L le 11 Mar 2021
and how is this applied to the raw siganl?
filtfilt(sos, g, raw)?
  1 commentaire
Star Strider
Star Strider le 11 Mar 2021
Yes!
raw_filtered = filtfilt(sos, g, raw);
.

Connectez-vous pour commenter.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by