Hi
I dont have a great deal of experiance in matlab and would like some advice on detecting breathing,the samples taken in the figures attached are raw ADC inputs to matlab with no filtering , is there firstly something I could do to improve the waveforms? (pre filtering)
Also what is the best method (most reliable) to detect there is breathing and the rate of the breathing.
figures attached baseline(no one on the bed), Breathing (normal) and breathing2(shallow)
Thank you in advance for any help you can offer.
Kind Regards
David

 Respuesta aceptada

Mathieu NOE
Mathieu NOE el 27 de Mayo de 2021

0 votos

hello David
yes you can clear tell that the bed is not empty and that someone is actually breathing by either saying the time signal has amplitude above 100 (so let's compute a smoothed rectified version of this signal) , this can be also observed in the frequency spectrum has you have peaks showing up between 0.1 and 1 Hz
to compite the rate of breathing you can either pick the highest amplitude peak in the fft spectrum (and find it's corresponding frequency) or you can compute the period between two zero crossing values (works also with a non zero threshold) as example attached shows
hope it helps
all the best

14 comentarios

David Jones
David Jones el 27 de Mayo de 2021
Hi Mathieu
Thank you for responding to my question.
I have downloaded your files and tried them, they look promising. The only problem is they dont seem to work with my Data, firstly after running I get :
Warning: Ignoring extra legend entries.
> In legend>process_inputs (line 602)
In legend>make_legend (line 334)
In legend (line 278)
In microwave (line 118)
Warning: Ignoring extra legend entries.
It displays the Data but not the crosses I have attached my most recent Data File please can you take a look.
Kind Regards
David
Mathieu NOE
Mathieu NOE el 27 de Mayo de 2021
hello again
here no problem with my R2020b
this is my code and the output : ( x axis in samples not in seconds as sampling rate is unknown to me)
clc
clearvars
load('Raw_Data.mat')
y = double(raw_ad_data_sine); % conversion to double
n=length(y);
x=(1:n);
threshold = 0.5; % your value here
[t0_pos,s0_pos,t0_neg,s0_neg]= crossing_V7(y,x,threshold,'linear'); % positive (pos) and negative (neg) slope crossing points
% ind => time index (samples)
% t0 => corresponding time (x) values
% s0 => corresponding function (y) values , obviously they must be equal to "threshold"
figure(1)
plot(x,y,t0_pos,s0_pos,'+r',t0_neg,s0_neg,'+g','linewidth',2,'markersize',12);grid on
legend('signal','positive slope crossing points','negative slope crossing points');
David Jones
David Jones el 27 de Mayo de 2021
HI Mathieu
Thanks for this help its been invaluable, I guess I am not calculating the correct X axis can you please show me how to display the correct timing on my sample, the sample rate is 0.01 number of samples 6000
Thank you once again
Kind regards
David
Mathieu NOE
Mathieu NOE el 27 de Mayo de 2021
No problem
just to understand, when you say sample rate is 0.01 , so between two samples we have dt = 100 seconds ?
Mathieu NOE
Mathieu NOE el 27 de Mayo de 2021
now this is an improved version of my code, assuming between two samples we have dt = 100 seconds
I added some high frequency filtering to avoid the zero crossing function to be "fooled" by the noise
then I computed the time interval between succesive positive slope crossing points (therefore you can get the frequency too
I have the feeling I don't have the right sampling rate here , 100 seconds between two samples seems very long for me
i also lifted the threshold to 100, so when there is no signal you would get no points
clc
clearvars
load('Raw_Data.mat')
y = double(raw_ad_data_sine); % conversion to double
n=length(y);
dt = 100;
x=(1:n)*dt;
threshold = 100; % your value here
% remove first some high frequency noise
yy = smoothdata(y,'gaussian',10);
[t0_pos,s0_pos,t0_neg,s0_neg]= crossing_V7(yy,x,threshold,'linear'); % positive (pos) and negative (neg) slope crossing points
% ind => time index (samples)
% t0 => corresponding time (x) values
% s0 => corresponding function (y) values , obviously they must be equal to "threshold"
figure(1)
plot(x,yy,t0_pos,s0_pos,'+r',t0_neg,s0_neg,'+g','linewidth',2,'markersize',12);grid on
legend('signal','positive slope crossing points','negative slope crossing points');
xlabel('Time (s)');
% let's compute the period between crossing points , then frequency
period_pos = diff(t0_pos); % seconds
freq_pos = 1./period_pos; % Hz
figure(2)
plot(t0_pos(2:end),period_pos,'+r','linewidth',2,'markersize',12);grid on
xlabel('Time (s)');
ylabel('period (s)');
figure(3)
plot(t0_pos(2:end),freq_pos,'+r','linewidth',2,'markersize',12);grid on
xlabel('Time (s)');
ylabel('Frequency (Hz)');
David Jones
David Jones el 28 de Mayo de 2021
Hi Mathieu
Thank you for your excellent help I have the code working now, I do have a couple of questions on the raw data file all of the frequency should almost be the same I think where the peaks are longer will be the time constant on the capacitors at this frequency ie charging and discharging is there any way to clean these up a little in Matlab.
Also what is the best way with the information in period_pos and freq_pos to basically say there is a xx% chance of breathing.
But once again thank you for your great help
Kind Regards
David
Mathieu NOE
Mathieu NOE el 28 de Mayo de 2021
hi David
I coud add a bit of stopband or bandpass filtering to remove the unwanted frequencies
what is the frequency range for the capacitors (very low I suppose) ?
what is the frequency range for normal breathing ?
David Jones
David Jones el 28 de Mayo de 2021
Hi Mathieu
The electronic high pass is 0.1 and the low pass is 0.45 breathing is around 0.15 to 0.4 hertz.
Thanks for your help on this
Kind Regards
David
Mathieu NOE
Mathieu NOE el 28 de Mayo de 2021
So I made some mods in the code :
  • added a bandpass filter to remove signal outside the specified range
  • BTW , my sampling rate was incorrect so I changed that too
  • I also changed my crossing_V7 subfunction so that the incoming signal is completely "flat" , no crossing point data can be found so you get empty output : this is the situation when no breathing signal is present
  • I added a histogram count so you can tell how many times at which frequencies the signal crossed the threshold value; again, falt signal will genrerate empty data and plot (try it)
attached the updated codes
David Jones
David Jones el 1 de Jun. de 2021
Hi Mathieu
Thank you for your excellent help, is there any way we can use the negative going wave forms as well?
Kind Regards
David
David Jones
David Jones el 1 de Jun. de 2021
Hi Mathieu
I decided to put a xtal locked 250m Hertz signal in to test the script, whilst the FFT lock perfectly can you please take a look at the histagram it doesnt seem to be accurate?.
Kind Regards
David
Mathieu NOE
Mathieu NOE el 1 de Jun. de 2021
hello
see the mods below , same frequency resolution now and same x axis span
axisHandleCh5 = subplot(5,1,5);
% h = histogram(freq_pos,"BinWidth",0.05)
h = histogram(freq_pos,"BinWidth",mean(diff(f_axis)))
h.BinLimits = [0 1];
xlabel('Frequency (Hz)');
ylabel('Counts');
David Jones
David Jones el 1 de Jun. de 2021
Great thanks for all your help
Mathieu NOE
Mathieu NOE el 1 de Jun. de 2021
my pleasure !

Iniciar sesión para comentar.

Más respuestas (0)

Productos

Etiquetas

Preguntada:

el 27 de Mayo de 2021

Comentada:

el 1 de Jun. de 2021

Community Treasure Hunt

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

Start Hunting!

Translated by