Filter löschen
Filter löschen

Bandpass filter vs sequential high and lowpass filter in Matlab: weird difference

17 Ansichten (letzte 30 Tage)
I am trying to bandpass a neural signal acquired at 20kHz between 0.5 and 100 Hz. I have tried to do it in two ways. The first way is to sequentially highpass and lowpass the signal and the second one is to use the bandpass function in Matlab. To my surprise, the results were dramatically different. See image below:
Here is the code:
clear
close all
load('bandpass_vs_seq_lo_and_hi_pass','tr','fs') % loads variable called tr and fs
% tr is the signal vector and fs is the sampling rate, 20kHz
padlen=0.01; % padding length in secs to remove transients at signal start and end
padn=padlen*fs; % padding length in samples
f_lo=0.5; % lo cutoff
f_hi=100; % hi cutoff
tvec=(1/fs:1/fs:1/fs*length(tr));
figure
ax1=subplot(3,1,1);
ax2=subplot(3,1,2);
ax3=subplot(3,1,3);
% sequential highpass and lowpass filter
% hipass filter
nutr=[flipud(tr(1:padn));tr;flipud(tr(end-(padn-1):end))]; % prefixing and appending signal
[filtr,~]=highpass(nutr,f_lo,fs);
filtr=filtr(padn+1:end-padn); % removing prefixed and appended parts
tr1=filtr;
% lopass filter
nutr=[flipud(tr1(1:padn));tr1;flipud(tr1(end-(padn-1):end))];
[filtr2,~]=lowpass(nutr,f_hi,fs);
filtr2=filtr2(padn+1:end-padn);
tr1=filtr2;
% bandpass filter
nutr=[flipud(tr(1:padn));tr;flipud(tr(end-(padn-1):end))];
[filtr,~]=bandpass(nutr,[f_lo,f_hi],fs);
filtr=filtr(padn+1:end-padn);
tr2=filtr;
plot(ax1,tvec,tr)
plot(ax2,tvec,tr1)
plot(ax3,tvec,tr2)
xlabel(ax3,'Time (s)')
title(ax1,'Original signal, fs=20kHz')
title(ax2,'Sequential high pass and lowpass (0.5 to 100 Hz)')
title(ax3,'Bandpass (0.5 to 100 Hz)')
Can anyone shed light on what is going on here?
Also asked here:
https://dsp.stackexchange.com/questions/73407/bandpass-filter-vs-sequential-high-and-lowpass-filter-in-matlab-weird-differenc
  3 Kommentare
Anand Kulkarni
Anand Kulkarni am 28 Feb. 2021
Thanks @Mathieu NOE It was very useful to confirm that this is weird. The computational cost is also very strange. I agree that the good old butter followed by filtfilt looks good and gets done in a reasonable time.
Mathieu NOE
Mathieu NOE am 1 Mär. 2021
hello
just minor improvement, if you detrend (remove mean value of your signal), you can probably reduce the amount of padding needed
tr = tr -mean(tr );

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Mathieu NOE
Mathieu NOE am 24 Feb. 2021
I prefer this code ... faster and I know what filters I use
i changed the input signal random + negative constant (to mimic your data)
I increased padding length to 2 secs to be coherent with the time constant of a 0.5 Hz high pass filter
and also both sequential and single bandpass filter outputs have same amplitude
fs = 20e3;
tr = randn(fs*10,1)-60;
% tr is the signal vector and fs is the sampling rate, 20kHz
padlen=2; % padding length in secs to remove transients at signal start and end
padn=padlen*fs; % padding length in samples
f_lo=0.5; % lo cutoff
f_hi=100; % hi cutoff
tvec=(1/fs:1/fs:1/fs*length(tr));
figure
ax1=subplot(3,1,1);
ax2=subplot(3,1,2);
ax3=subplot(3,1,3);
% sequential highpass and lowpass filter
% hipass filter
nutr=[tr(padn:-1:1);tr;tr(end:-1:end-(padn-1))]; % prefixing and appending signal
N = 2; % MN
[B,A] = butter(N,f_lo*2/fs,'high'); % MN
filtr= filtfilt(B,A,nutr); % MN
% lopass filter
N = 2; % MN
[B,A] = butter(N,f_hi*2/fs,'low'); % MN
filtr2= filtfilt(B,A,filtr); % MN
filtr2=filtr2(padn+1:end-padn);
tr1=filtr2;
% bandpass filter
nutr=[tr(padn:-1:1);tr;tr(end:-1:end-(padn-1))]; % prefixing and appending signal
N = 2; % MN
[B,A] = butter(N,[f_lo f_hi]*2/fs); % MN
filtr= filtfilt(B,A,nutr); % MN
filtr=filtr(padn+1:end-padn);
tr2=filtr;
plot(ax1,tvec,tr)
plot(ax2,tvec,tr1)
plot(ax3,tvec,tr2)
xlabel(ax3,'Time (s)')
title(ax1,'Original signal, fs=20kHz')
title(ax2,'Sequential high pass and lowpass (0.5 to 100 Hz)')
title(ax3,'Bandpass (0.5 to 100 Hz)')

Weitere Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by