Hi! I recently recorded an EEG signal at 50K Hz sampling rate. The signal was band passed at 1-500Hz before it was digitalized. Now I wanted to do a digital fitlering to this data, which is a low pass filter to cut off bands with frequency larger than 10Hz. But I found it hard to achieve. My code was like this: filter_n=20*sample_rate; cutoff=10; %cutoff frequency lowpass=fir1(filter_n,cutoff*2/sample_rate,'low'); y_lowpass=filter(lowpass,1,y); But I found the low-passed signal still had much power in bands larger than 10Hz. Can someone help me out? Thanks!
John Williams answered .
2025-11-20
Your issue may be due to insufficient filter order or improper design of the FIR filter. To apply an effective low-pass filter to your EEG signal, here are a few key suggestions:
Increase Filter Order:
Check the Normalized Cutoff Frequency:
Use a Window Method or Different Design Approach:
fir1 function uses a window-based design method, but you might achieve better performance with an alternative design approach, like using designfilt.Analyze the Filter's Frequency Response:
Here’s an updated and more robust way to design and apply the filter:
% Given parameters
sample_rate = 50000; % 50 kHz
cutoff = 10; % Cutoff frequency in Hz
filter_order = 500; % Increase filter order for sharper cutoff
% Normalize cutoff frequency
normalized_cutoff = cutoff / (sample_rate / 2);
% Design the low-pass FIR filter
lowpass = fir1(filter_order, normalized_cutoff, 'low');
% Analyze the frequency response of the filter
fvtool(lowpass, 1);
% Apply the filter to your EEG data
y_lowpass = filter(lowpass, 1, y);
% Plot the original and filtered signals
t = (0:length(y)-1) / sample_rate; % Time vector
figure;
subplot(2, 1, 1);
plot(t, y);
title('Original Signal');
xlabel('Time (s)');
ylabel('Amplitude');
subplot(2, 1, 2);
plot(t, y_lowpass);
title('Low-pass Filtered Signal');
xlabel('Time (s)');
ylabel('Amplitude');
Filter Order:
Frequency Normalization:
Filter Verification:
fvtool to visualize the frequency response of the filter and verify that it attenuates frequencies above 10 Hz effectively.designfiltInstead of fir1, you can use designfilt for more control over the filter design:
% Design a low-pass FIR filter with designfilt
d = designfilt('lowpassfir', ...
'FilterOrder', filter_order, ...
'CutoffFrequency', cutoff, ...
'SampleRate', sample_rate);
% Analyze the frequency response
fvtool(d);
% Apply the filter
y_lowpass = filter(d, y);
To ensure that frequencies above 10 Hz are removed:
fft and plot to visualize the power in each frequency band.
% FFT of the original signal
Y_orig = fft(y);
f = linspace(0, sample_rate / 2, floor(length(Y_orig) / 2) + 1);
% FFT of the filtered signal
Y_filtered = fft(y_lowpass);
% Plot the magnitude spectra
figure;
plot(f, abs(Y_orig(1:length(f))), 'b');
hold on;
plot(f, abs(Y_filtered(1:length(f))), 'r');
title('Frequency Spectrum');
xlabel('Frequency (Hz)');
ylabel('Magnitude');
legend('Original', 'Filtered');
Let me know if you need additional guidance!