2

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

4

3 回答 3

2

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

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 的任一侧填充一个假,所以

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

在此处输入图像描述

于 2013-04-23T11:24:08.800 回答
2

你怎么看内置

findpeaks(data,'Name',value)

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

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

我希望这有帮助。

于 2013-04-23T11:24:20.003 回答
0

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

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

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

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

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

于 2014-02-23T21:38:32.130 回答