What filtration should be used for a respiratory signal between 5 and 60 breaths per minute?

22 vues (au cours des 30 derniers jours)
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);

Réponse acceptée

William Rose
William Rose le 12 Jan 2023
%% Load data
a=importdata('RAW_signal.txt');
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
figure; subplot(211)
plot(t,x,'-r',t,y,'-b',locs,-pks,'k^');
title('Respiration'); grid on; xlabel('Time (s)'); ylabel('Amplitude (mV)');
legend('Raw','Filtered','Minima','Location','Southeast');
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.

Plus de réponses (1)

William Rose
William Rose le 11 Jan 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.
  8 commentaires
Pawel Slazak
Pawel Slazak le 12 Jan 2023
The signal was obtained artificially in order to write an algorithm.

Connectez-vous pour commenter.

Produits


Version

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by