Filter EKG with artifacts (respiratory or movement of electrode)

5 ビュー (過去 30 日間)
Siria Fumagalli
Siria Fumagalli 2021 年 12 月 22 日
コメント済み: Mathieu NOE 2021 年 12 月 22 日
Hi Everybody,
I'm doing a resarch with a t-shirt with built-in sensors, in particular I'm doing HRV analyses, I'm not very good at signal filtering so I'm asking for help.
From this t-shirt i can extract the respiratory signal and the EKG both attached here, in both file the first raw is time in seconds.
I would like to clean this EKG (and other similar of this patient) so that i can extract reliably peak R, in this case I attached also the respiratory signal as I think the fluctuations in the signal may be due to that.
Thank for the help.
  2 件のコメント
Star Strider
Star Strider 2021 年 12 月 22 日
Mathieu NOE
Mathieu NOE 2021 年 12 月 22 日
hello
my 2 cents
tried rapidely some filering and other stuff on the breath signal - not sure if this will help you ...
load('breath.mat')
time = Breath(1,:);
signal = detrend(Breath(2,:),'linear');
signal = signal-min(signal); % so the min is set at zero
dt = mean(diff(time));
Fs = 1/dt;
%smoothed curve
signal_sm = smoothdata(signal,'gaussian',500);
% difference = dynamic portion
signal_dyn = signal-signal_sm;
% computing "threshold" level crossing points on the smoothed signal
threshold1 = max(signal_sm)*0.7; % your value here
[t0_pos1,s0_pos1,t0_neg1,s0_neg1]= crossing_V7(signal_sm,time,threshold1,'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"
% computing "threshold" level crossing points on the dynamic signal
threshold2 = max(signal_dyn)*0.25; % your value here
[t0_pos2,s0_pos2,t0_neg2,s0_neg2]= crossing_V7(signal_dyn,time,threshold2,'linear'); % positive (pos) and negative (neg) slope crossing points
figure(1);
subplot(211),plot(time,signal,time,signal_sm);
plot(time,signal,time,signal_sm,time,threshold1*ones(size(time)),'k--',t0_pos1,s0_pos1,'dr',t0_neg1,s0_neg1,'dg','linewidth',2,'markersize',12);grid on
xlabel('time (s)');
legend('signal','signal smoothed','threshold','positive slope crossing points','negative slope crossing points');
subplot(212),plot(time,signal_dyn)
subplot(212),plot(time,signal_dyn,time,threshold2*ones(size(time)),'k--',t0_pos2,s0_pos2,'dr',t0_neg2,s0_neg2,'dg','linewidth',2,'markersize',12);grid on
legend('signal dynamic','threshold','positive slope crossing points','negative slope crossing points');
xlabel('time (s)');
period1 = diff(t0_pos1) % period in seconds for smoothed signal
period2 = diff(t0_pos2) % period in seconds for dynamic signal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [t0_pos,s0_pos,t0_neg,s0_neg] = crossing_V7(S,t,level,imeth)
% [ind,t0,s0,t0close,s0close] = crossing_V6(S,t,level,imeth,slope_sign) % older format
% CROSSING find the crossings of a given level of a signal
% ind = CROSSING(S) returns an index vector ind, the signal
% S crosses zero at ind or at between ind and ind+1
% [ind,t0] = CROSSING(S,t) additionally returns a time
% vector t0 of the zero crossings of the signal S. The crossing
% times are linearly interpolated between the given times t
% [ind,t0] = CROSSING(S,t,level) returns the crossings of the
% given level instead of the zero crossings
% ind = CROSSING(S,[],level) as above but without time interpolation
% [ind,t0] = CROSSING(S,t,level,par) allows additional parameters
% par = {'none'|'linear'}.
% With interpolation turned off (par = 'none') this function always
% returns the value left of the zero (the data point thats nearest
% to the zero AND smaller than the zero crossing).
%
% check the number of input arguments
error(nargchk(1,4,nargin));
% check the time vector input for consistency
if nargin < 2 | isempty(t)
% if no time vector is given, use the index vector as time
t = 1:length(S);
elseif length(t) ~= length(S)
% if S and t are not of the same length, throw an error
error('t and S must be of identical length!');
end
% check the level input
if nargin < 3
% set standard value 0, if level is not given
level = 0;
end
% check interpolation method input
if nargin < 4
imeth = 'linear';
end
% make row vectors
t = t(:)';
S = S(:)';
% always search for zeros. So if we want the crossing of
% any other threshold value "level", we subtract it from
% the values and search for zeros.
S = S - level;
% first look for exact zeros
ind0 = find( S == 0 );
% then look for zero crossings between data points
S1 = S(1:end-1) .* S(2:end);
ind1 = find( S1 < 0 );
% bring exact zeros and "in-between" zeros together
ind = sort([ind0 ind1]);
% and pick the associated time values
t0 = t(ind);
s0 = S(ind);
if ~isempty(ind)
if strcmp(imeth,'linear')
% linear interpolation of crossing
for ii=1:length(t0)
%if abs(S(ind(ii))) >= eps(S(ind(ii))) % MATLAB V7 et +
if abs(S(ind(ii))) >= eps*abs(S(ind(ii))) % MATLAB V6 et - EPS * ABS(X)
% interpolate only when data point is not already zero
NUM = (t(ind(ii)+1) - t(ind(ii)));
DEN = (S(ind(ii)+1) - S(ind(ii)));
slope = NUM / DEN;
slope_sign(ii) = sign(slope);
t0(ii) = t0(ii) - S(ind(ii)) * slope;
s0(ii) = level;
end
end
end
% extract the positive slope crossing points
ind_pos = find(sign(slope_sign)>0);
t0_pos = t0(ind_pos);
s0_pos = s0(ind_pos);
% extract the negative slope crossing points
ind_neg = find(sign(slope_sign)<0);
t0_neg = t0(ind_neg);
s0_neg = s0(ind_neg);
else
% empty output
ind_pos = [];
t0_pos = [];
s0_pos = [];
% extract the negative slope crossing points
ind_neg = [];
t0_neg = [];
s0_neg = [];
end
end

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

回答 (0 件)

カテゴリ

Help Center および File ExchangeMultirate Signal Processing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by