What filtration should be used for a respiratory signal between 5 and 60 breaths per minute?
24 visualizaciones (últimos 30 días)
Pawel Slazak el 11 de En. de 2023
I have applied LPF and HPF filtering, but for a low-frequency respiratory signal, the signal after HPF is distorted and edge detection is incorrect, as can be seen in the attached photo. Is it possible to use some kind of filtration that can handle the respiratory signal range of 5-60 breaths per minute? Is it better to use a findpeaks function with appropriate limitations and only LPF filtering as in diagram 2 in the attached photo?
% ------------- LPF ------------------------------
N = 5; % Order
Fstop = 1.4; % Stopband Frequency
Astop = 30; % Stopband Attenuation (dB)
Fs = 25; % Sampling Frequency
h = fdesign.lowpass('n,fst,ast', N, Fstop, Astop, Fs);
hfiltLP = design(h, 'cheby2', 'SystemObject', true);
% ------------- HPF ------------------------------
N = 4; % Order
Fstop = 4/60; % Stopband Frequency min 4 oddechow na minute
Astop = 60; % Stopband Attenuation (dB)
Fs = 25; % Sampling Frequency
h = fdesign.highpass('n,fst,ast', N, Fstop, Astop, Fs);
hfiltHP = design(h, 'cheby2', 'SystemObject', true);
William Rose el 12 de En. de 2023
%% Load data
x=a.data(:,1); %x=channel 1
fs=25; %sampling frequency (Hz)
t=(0:length(x)-1)/fs; %time vector
%% Filter data
fco=1.4; %lowpass cutoff (Hz)
[b,a]=butter(4,fco/(fs/2)); %4th order Butterworth lowpass
y=filter(b,a,x-mean(x)); %filter the data
y=y+mean(x); %add back the mean value
%% Find minima
[pks,locs]=findpeaks(-y,fs,'MinPeakProminence',10); %find peaks and peak locations
%% Compute rate
rRate=60./diff(locs); %rate associated with each breath (1/minute)
tRate=locs(2:end); %ending time of each breath
%% Plot results
title('Respiration'); grid on; xlabel('Time (s)'); ylabel('Amplitude (mV)');
subplot(212); stairs(tRate,rRate,'-r'); grid on;
title('Respiratory Rate'); xlabel('Time (s)'); ylabel('Rate (bpm)');
The code above finds and plots the the minima. It also computes and plots the respiratory rate versus time. I chose to associate each breath's rate with the ending time of each breath, and I used the stairs() plot for the rate, because that is how a real time app would work. You said you hope to implement this in real time.
Más respuestas (1)
William Rose el 11 de En. de 2023
@Pawel Slazak, pease attach the raw data.
Please explain what your goal is, because this will determine what approach to take.
If it is your goal to determine the respiratory rate, then it does not matter if we use upward or downward slope of the signal to mark each breath, as long as we find a consistent way that is not affected by the noise on the signal.
If it is your goal to identify the time of the start of each inspiration, then please specify whether more positive values of the signal correspond to greater or lesser lung volume. We will want to identify the minimum points of the lung volume signal.
It will not be hard to do this. We just need to choose the right filter setting, and we must decide if we will use peaks in filtered dV/dt to do it - which depends on your answers to the quesitons above.
Please upload the raw data, as a text file or as a .mat file.