Detect beginning and end of inhalation in respiration signal

30 ビュー (過去 30 日間)
Alexis
Alexis 2018 年 5 月 18 日
コメント済み: Image Analyst 2020 年 11 月 2 日
This signal was collected from a respiratory effort belt transducer, sampled during speech production (fs = 1 kHz). I have many trials of data to process, so I hoped to do this semi-automatically and correct where needed.
I'd like to analyse the duration of speech-related inhalation events. At first, I thought to use findpeaks() to mark local minima and maxima. I planned to measure the time elapsed between paired troughs (i.e., beginning of pre-speech inhalation) and peaks (i.e., end of pre-speech inhalation/beginning of speech exhalation). Below is how I used findpeaks(), which in this case worked great.
But I'm now realizing that there are not always equal numbers of mini/maxima, and even then, pairing them appropriately is not always as straight-ahead as in the above example (e.g., two peaks but only one clear trough - which is the matching peak?). Moreover, sometimes this happens:
For above, I would choose the later, if less prominent, trough as my inhalation-initiation point.
Rather than simply measuring between minima/maxima, I think a better way to detect inhalations would be to look for their characteristic profile: smooth, steep, positive lines falling containing at least x samples. I have tried findchangepts() but the input arguments don't include parameters such as sign or slope.
Intuitively, I imagine a window moving in steps, testing the fit of an inhalation model, so long as the lengths of inhalations are free to vary (assuming a minimum threshold is reached).
Or, maybe all I need to look for are vectors of rising data points that meet a minimum number of elements.
I'm new to signal processing and I'm not sure where to look next - can anyone offer any keywords?
  3 件のコメント
Alexis
Alexis 2018 年 5 月 20 日
編集済み: Alexis 2018 年 5 月 20 日

Thank you, Jonas! I attached an example of the signal. Below I have annotated (via visual inspection) where the inhalations approximately begin and end. Where the slope wasn't perfectly continuous, I eyeballed its overall trajectory within a given window, which I would also want to do programmatically.

load('breath.mat','breath')
inhale = [103; 4284; 10599; 16892; 20776; 23713];
exhale = [708; 4916; 11244; 17623; 21019; 24259];
loopX = max([numel(inhale) numel(exhale)]);
plot(breath);
hold on
for i = 1:loopX
    try
        plot(inhale(i),breath(inhale(i)),'r*')
    end
     plot(exhale(i),breath(exhale(i)),'r*')
end
Alexis
Alexis 2020 年 10 月 12 日
編集済み: Alexis 2020 年 10 月 12 日
For anyone else who needs it, I have written a function incorporating Jonas' suggestions for automatically detecting inhalation/exhalation points:

サインインしてコメントする。

採用された回答

jonas
jonas 2018 年 5 月 20 日
編集済み: jonas 2018 年 5 月 20 日
Based on the data provided in the comments, here's one way to use findchangepts to locate continuous steep slopes. As previously stated, I'm not an expert in signal processing so I'm sure there are more accurate methods, but this would be one option.
You can play with 'MinThreshold' to find a more suitable threshold. Reducing the value gives you more changepts.
clear all;close all
load('breath.mat','breath')
inhale = [103; 4284; 10599; 16892; 20776; 23713];
exhale = [708; 4916; 11244; 17623; 21019; 24259];
loopX = max([numel(inhale) numel(exhale)]);
subplot(4,1,1)
plot(breath);
title('target points')
hold on
for i = 1:loopX
try
plot(inhale(i),breath(inhale(i)),'r*')
end
plot(exhale(i),breath(exhale(i)),'r*')
end
%slope analysis
subplot(4,1,2);hold on
ind=findchangepts(breath,'Statistic','linear','MinThreshold',0.5)
plot(breath)
title('changepoints, calculated with minthreshold=0.5')
plot(ind,breath(ind),'rx')
subplot(4,1,3)
values=breath(ind);
%remove changepts with negative slope
dx=diff(ind);
dy=diff(breath(ind));
slope=dy./dx;
plot(slope)
thres=1e-4; %set minimum slope
a=find(slope>thres)
i_start=ind(a);
i_end=ind(a+1);
subplot(4,1,3);hold on
plot(breath,'b')
title('changepoints with slope > threshold')
plot(i_start,breath(i_start),'rx',...
i_end,breath(i_end),'rx')
%remove changepts between start and end of inhalation process
b=find(i_start(2:end)==i_end(1:end-1))
i_end(b)=[];
i_start(b+1)=[];
subplot(4,1,4);hold on
title('removed intermediate points')
plot(breath,'b')
plot(i_start,breath(i_start),'rx',...
i_end,breath(i_end),'rx')
  6 件のコメント
athraa sab
athraa sab 2020 年 11 月 1 日
any data from web can u help me??/
Image Analyst
Image Analyst 2020 年 11 月 2 日
No. I am not a physician. I don't have any data for you. Who is sponsoring your research? Again, they should have the data you need. We don't have any.

サインインしてコメントする。

その他の回答 (1 件)

Image Analyst
Image Analyst 2018 年 5 月 19 日
編集済み: Image Analyst 2018 年 5 月 19 日
I'd try findpeaks(). It has tons of options (many of which are tricky) to help you find only the peaks you need. To find valleys, simply pass the negative of the signal into findpeaks.
Attach your signal data if you need more help - make it easy for people to help you, not hard.
  1 件のコメント
Alexis
Alexis 2018 年 5 月 20 日
編集済み: Alexis 2018 年 5 月 20 日
In my question, I mentioned that findpeaks() hasn't been as helpful for me as I'd hoped (and show why in plots). Namely, it's great for selecting inhalation peaks, but the absolute valleys don't always indicate the initiation of an inhalation.
Hence why I asked for keywords, instead of posting my code (which I already have made and does what I want, but may not be the right approach).
I've edited my question so this is more clear, thanks.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeDescriptive Statistics についてさらに検索

製品


リリース

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by