matlab中原始心电信号的QRS波检测(峰值)

matlab中原始心电信号的QRS波检测(峰值),matlab,signal-processing,Matlab,Signal Processing,我想找到原始ecg信号的峰值,这样我就可以计算每分钟心跳(bpm)。 我已经用matlab编写了一个代码,我在下面附上了它。在下面的代码中,我无法正确地找到阈值点,这将帮助我找到峰值,从而找到bpm %input the signal into matlab [x,fs]=wavread('heartbeat.wav'); subplot(2,1,1) plot(x(1:10000),'r-') grid on %lowpass filter the input signal with

我想找到原始ecg信号的峰值,这样我就可以计算每分钟心跳(bpm)。 我已经用matlab编写了一个代码,我在下面附上了它。在下面的代码中,我无法正确地找到阈值点,这将帮助我找到峰值,从而找到bpm

%input the signal into matlab

[x,fs]=wavread('heartbeat.wav');
subplot(2,1,1)
plot(x(1:10000),'r-')
grid on



%lowpass filter the input signal with cutoff at 100hz
h=fir1(30,0.3126);     %normalized cutoff freq=0.3126
y=filter(h,1,x);

subplot(2,1,2)
plot(y(1:10000),'b-')
grid on



% peaks are seen as pulses(heart beats)
beat_count=0;
for p=2:length(y)-1
    th(p)=abs(max(y(p)));
    if(y(p) >y(p-1) && y(p) >y(p+1) && y(p)>th(p))
        beat_count=beat_count+1;
    end
end

N = length(y);
duration_seconds=N/fs;
duration_minutes=duration_seconds/60;
BPM=beat_count/duration_minutes;
bpm=ceil(BPM);

请帮助我,因为我是matlab新手

我建议更改代码的这一部分

beat_count=0;
for p=2:length(y)-1
    th(p)=abs(max(y(p)));
    if(y(p) >y(p-1) && y(p) >y(p+1) && y(p)>th(p))
        beat_count=beat_count+1;
    end
end
这绝对是有缺陷的。我不确定你的逻辑,但是这个呢。我们正在寻找峰值,但只寻找高峰值,因此首先让我们设置一个阈值(您必须将其调整为一个合理的数字),并剔除低于该值的所有内容,以去除较小的峰值:

th = max(y) * 0.9; %So here I'm considering anything less than 90% of the max as not a real peak... this bit really depends on your logic of finding peaks though which you haven't explained
Yth = zeros(length(y), 1);
Yth(y > th) = y(y > th);
好的,我建议你现在画y和Yth,看看代码做了什么。现在要找到峰值,我的逻辑是我们要寻找局部极大值,即函数的一阶导数从正变为负的点。所以我要找到一个非常简单的一阶导数的数值近似,通过找到信号上每个连续点之间的差值:

Ydiff = diff(Yth);
不,我想找到信号从正到负的方向。所以我要让所有的正值都等于零,所有的负值都等于一:

Ydiff_logical = Ydiff < 0;
现在数一数山峰:

sum(Ypeaks)
请注意,由于使用了diff,所以在绘制紫色时,我们应该在Ypeaks的任一侧填充一个false

Ypeaks = [false; Ypeaks; false];
好的,这里有很多matlab,我建议你一行一行地运行每一行,通过绘制每一行的结果和双击matlab工作区中的变量来检查变量,以了解每一步发生的情况

示例:(信号
PeakSig
取自)并使用以下参数绘图:

plot(x(Ypeaks),PeakSig(Ypeaks),'k^','markerfacecolor',[1 0 0]);

您认为内置的

findpeaks(data,'Name',value)
功能?您可以选择不同的峰值检测逻辑:

'MINPEAKHEIGHT'
'MINPEAKDISTANCE'
'THRESHOLD'
'NPEAKS'
'SORTSTR'

我希望这能有所帮助。

你知道,QRS波群并不总是具有最大振幅,对于病理性ECG来说,它可以表现为几个微小的振荡,而不是一个高振幅的峰值

因此,您可以尝试一种由我测试过的好算法:检测标准假定为信号的高绝对变化率,在给定的时间间隔内取平均值

算法: -50/60 Hz滤波器(例如,对于20毫秒的50 Hz滑动窗口,可以使用) -自适应hipass滤波器(用于基线漂移) -查找信号的第一个导数x' -平方导数(x')^2 -应用滑动平均窗,QRS波群的宽度约为100-150毫秒(您将获得一些具有QRS波宽度的“矩形”信号) -使用简单阈值(例如前3秒最大值的1/3)确定近似位置或R -在源ECG中,找到R位置+-100毫秒内的局部最大值

但是,您仍然必须消除伪影和异常值(例如,当电极连接失败时的浪涌)


此外,您可以从本书中找到很多有用的信息:“R.M.Rangayyan-生物医学信号分析”

嗨,我建议您解释峰值检测算法背后的逻辑,而不是期望人们仅仅从代码中理解它。另外,
abs(max(y(p))
没有多大意义,因为
y(p)
是一个标量,所以
max(y(p))
只是
y(p)
,也许你的意思是
max(y)
?@Dan yup…我的意思是max(y)…通过找到阈值,我可以将y的值与其之前的值进行比较,其下一个值和阈值。如果该值大于所有3种情况,则将其视为峰值。100 Hz是从ECG数据中过滤QRS的极高截止值。你可能想要15-30赫兹左右的频率。您还需要一个截止频率约为5 Hz的高通滤波器,以消除基线漂移等。除此之外,您可能还应该使用
filtfilt
,这样就不会出现相位失真-毕竟,在这种情况下,您对时间历史感兴趣。你也可以考虑使用,它工作得很好。我也在iOS中应用同样的东西。我希望你能得到解决方案,但是有两种方法,你可以找到斜率,或者你从旧坐标到新的距离,我也很高兴如果我在IOSNONT得到帮助,这是信号处理工具箱的一部分。但是很酷!Yth=零(长度(y),1);Yth(y>th)=y(y>th);我不明白你为什么要给Yth赋值零,我想知道你用哪个matlab版本作为PeakSig在我的版本中找不到!是的,
PeakSig
正如我在回答中所说,只是我从文档中获取的一个信号。它不是内置在matlab中,而是来自我提供的链接!这只是一个例子,你必须使用你的ECG信号,我必须生成一个信号,因为你没有提供信号。我指定零的原因是,所有低于阈值的都设置为零,以消除较小的峰值,这就是为什么只有前三个峰值(或者更准确地说,峰值至少是绝对最大值的90%)被检测到。我使用了你在上面帖子中建议的方法。但无法得到实际结果,即检测到实际的R峰值。附上图片链接。请指导我如何检测这些数字。哇,这是一个严重的噪音信号。是我还是你的滤波信号与未滤波信号相同。我建议您发布一个新问题,其中包含一些示例数据和实现此方法的代码,这样我们就可以看到您的错误所在。你有没有像@fpe建议的那样尝试
findpeaks
'MINPEAKHEIGHT'
'MINPEAKDISTANCE'
'THRESHOLD'
'NPEAKS'
'SORTSTR'