【问题标题】:QRS detection(peaks) of a raw ecg signal in matlabmatlab中原始心电信号的QRS检测(峰值)
【发布时间】:2013-04-23 10:49:09
【问题描述】:

我想找到原始心电图信号的峰值,以便计算每分钟的心跳次数 (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 新手

【问题讨论】:

  • 您好,我建议您解释一下您的峰值检测算法背后的逻辑,而不是期望人们仅仅从代码中理解它。另外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 Hz 的频率。您还需要一个截止频率约为 5 Hz 的高通滤波器来消除基线漂移等。除此之外,您可能应该使用filtfilt,因此没有相位失真 - 毕竟,在这种情况下您对时间历史的样子感兴趣。你也可以考虑使用the Pan & Tompkins algorithm,效果很好。
  • 我也在 ios 中应用了同样的东西我希望你能得到解决方案但是有两种方法可以找到坡度或者你得到从旧坐标到新坐标的距离,我也很高兴如果我在 ios 中获得帮助

标签: matlab signal-processing


【解决方案1】:

我建议更改这部分代码

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);

不,我想找出信号从正面变为负面的位置。所以我要让所有的正值都等于 0,所有的负值都等于 1:

Ydiff_logical = Ydiff < 0;

最后我想找到这个信号从零变为一的位置(但不是相反)

Ypeaks = diff(Ydiff_logical) == 1;

现在计算峰值:

sum(Ypeaks)

请注意,由于使用 diff,我们应该在 Ypeaks 的任一侧填充一个 false 来绘制目的

Ypeaks = [false; Ypeaks; false];

好的,所以那里有很多 matlab,我建议您逐行运行,并通过绘制每行的结果以及双击 matlab 工作区中的变量来检查变量以了解什么每一步都在发生。

示例:(信号 PeakSig 取自 http://www.mathworks.com/help/signal/ref/findpeaks.html)和绘图:

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

【讨论】:

  • Yth = zeros(length(y), 1); Yth(y > th) = y(y > th);我不明白您为什么要为 Yth 分配零,我想知道您使用的是哪个 matlab 版本,因为我没有找到 PeakSig!
  • 是的PeakSig,正如我在答案中所说,只是我从文档中获取的一个信号。它不是内置在matlab中的,它来自我提供的链接!这只是一个例子,你必须使用你的心电图信号,因为你没有提供信号,所以我必须编造一个信号。
  • 我分配零的原因是为了使低于阈值的所有内容都设置为零以消除较小的峰值,这就是为什么只有前三个峰值(或更准确地说是至少 90% 的峰值)的绝对最大值)被检测到。
  • 我使用了您在上面的帖子中建议的方法..但无法得到实际结果,即检测实际的 R 峰值。附上图片的链接..请指导我怎么做检测到此类数字..hostpic.org/view.php?filename=1304251341240092.jpg
  • 哇,这是一个非常嘈杂的信号。只是我还是您的过滤信号与未过滤的信号相同。我建议您发布一个新问题,其中包含一些示例数据和实现此方法的代码,以便我们可以看到您哪里出错了。你有没有像@fpe 建议的那样尝试findpeaks
【解决方案2】:

你对内置有什么看法

findpeaks(data,'Name',value)

功能?您可以选择不同的峰值检测逻辑:

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

我希望这会有所帮助。

【讨论】:

  • 请注意,这是信号处理工具箱的一部分。但是很酷!
【解决方案3】:

您知道,QRS 波群并不总是具有最大幅度,对于病理性心电图,它可以表现为几个轻微的振荡而不是一个高幅度的峰值。

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多