Amplitude increase after filter

27 ビュー (過去 30 日間)
Kcire L
Kcire L 2021 年 3 月 11 日
コメント済み: Star Strider 2021 年 3 月 11 日
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)

採用された回答

Star Strider
Star Strider 2021 年 3 月 11 日
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 件のコメント
Star Strider
Star Strider 2021 年 3 月 11 日
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.

サインインしてコメントする。

その他の回答 (4 件)

Kcire L
Kcire L 2021 年 3 月 11 日
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 2021 年 3 月 11 日
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 件のコメント
Kcire L
Kcire L 2021 年 3 月 11 日
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 2021 年 3 月 11 日
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.

サインインしてコメントする。


Kcire L
Kcire L 2021 年 3 月 11 日
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 件のコメント
Star Strider
Star Strider 2021 年 3 月 11 日
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.

サインインしてコメントする。


Kcire L
Kcire L 2021 年 3 月 11 日
and how is this applied to the raw siganl?
filtfilt(sos, g, raw)?
  1 件のコメント
Star Strider
Star Strider 2021 年 3 月 11 日
Yes!
raw_filtered = filtfilt(sos, g, raw);
.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeDigital Filter Design についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by