检测波浪中的模式
language-agnostic
machine-learning
7
0

我正在尝试从心电图读取图像并检测其中的每个主要波(P波,QRS复波和T波)。现在,我可以读取图像并得到一个代表(4.2; 4.4; 4.9; 4.7; ...)的矢量,表示心电图中的值,这是问题的一半。我需要一种算法,该算法可以遍历此向量,并检测何时每个波开始和结束。

这是其中一个图表的示例:

替代文字

如果它们始终具有相同的大小,则很容易,但是它并不起作用,或者如果我知道心电图会产生多少波,但它也可以变化。有人有想法吗?

谢谢!

更新中

我要实现的示例:

鉴于浪潮

替代文字

我可以提取向量

[0; 0; 20; 20; 20; 19; 18; 17; 17; 17; 17; 17; 16; 16; 16; 16; 16; 16; 16; 17; 17; 18; 19; 20; 21; 22; 23; 23; 23; 25; 25; 23; 22; 20; 19; 17; 16; 16; 14; 13; 14; 13; 13; 12; 12; 12; 12; 12; 11; 11; 10; 12; 16; 22; 31; 38; 45; 51; 47; 41; 33; 26; 21; 17; 17; 16; 16; 15; 16; 17; 17; 18; 18; 17; 18; 18; 18; 18; 18; 18; 18; 17; 17; 18; 19; 18; 18; 19; 19; 19; 19; 20; 20; 19; 20; 22; 24; 24; 25; 26; 27; 28; 29; 30; 31; 31; 31; 32; 32; 32; 31; 29; 28; 26; 24; 22; 20; 20; 19; 18; 18; 17; 17; 16; 16; 15; 15; 16; 15; 15; 15; 15; 15; 15; 15; 15; 15; 14; 15; 16; 16; 16; 16; 16; 16; 16; 16; 16; 15; 16; 15; 15; 15; 16; 16; 16; 16; 16; 16; 16; 16; 15; 16; 16; 16; 16; 16; 15; 15; 15; 15; 15; 16; 16; 17; 18; 18; 19; 19; 19; 20; 21; 22; 22; 22; 22; 21; 20; 18; 17; 17; 15; 15; 14; 14; 13; 13; 14; 13; 13; 13; 12; 12; 12; 12; 13; 18; 23; 30; 38; 47; 51; 44; 39; 31; 24; 18; 16; 15; 15; 15; 15; 15; 15; 16; 16; 16; 17; 16; 16; 17; 17; 16; 17; 17; 17; 17; 18; 18; 18; 18; 19; 19; 20; 20; 20; 20; 21; 22; 22; 24; 25; 26; 27; 28; 29; 30; 31; 32; 33; 32; 33; 33; 33; 32; 30; 28; 26; 24; 23; 23; 22; 20; 19; 19; 18; 17; 17; 18; 17; 18; 18; 17; 18; 17; 18; 18; 17; 17; 17; 17; 16; 17; 17; 17; 18; 18; 17; 17; 18; 18; 18; 19; 18; 18; 17; 18; 18; 17; 17; 17; 17; 17; 18; 17; 17; 18; 17; 17; 17; 17; 17; 17; 17; 18; 17; 17; 18; 18; 18; 20; 20; 21; 21; 22; 23; 24; 23; 23; 21; 21; 20; 18; 18; 17; 16; 14; 13; 13; 13; 13; 13; 13; 13; 13; 13; 12; 12; 12; 16; 19; 28; 36; 47; 51; 46; 40; 32; 24; 20; 18; 16; 16; 16; 16; 15; 16; 16; 16; 17; 17; 17; 18; 17; 17; 18; 18; 18; 18; 19; 18; 18; 19; 20; 20; 20; 20; 20; 21; 21; 22; 22; 23; 25; 26; 27; 29; 29; 30; 31; 32; 33; 33; 33; 34; 35; 35; 35; 0; 0; 0; 0;]

例如,我想检测

[19-37]中的P波

[51-64]中的QRS复合体

等等...

参考资料:
Stack Overflow
收藏
评论
共 8 个回答
高赞 时间 活跃

这是一个很好的问题!我有几点想法:

动态时间规整在这里可能是一个有趣的工具。您将为三个类别建立“模板”,然后使用DTW可以查看模板和信号“块”之间的相关性(将信号分解为0.5秒位,即0-.5)。 1-.6 .2-.7 ...)。我已经使用加速度计数据进行过类似的步态分析工作,效果很好。

另一个选择是组合的信号处理/机器学习算法。再次将信号分解为“块”。再次制作“模板”(每个类需要十几个左右),对每个块/模板进行FFT ,然后使用朴素贝叶斯分类器 (或另一个ML分类器,但是NB应该将其分类)为每个分类你的三个班。我还在步态数据上进行了尝试,能够获得高达98%的精度,并可以使用相对复杂的信号进行召回。让我知道这是如何工作的,这是一个非常令人兴奋的问题。

收藏
评论

我要做的第一件事就是简化数据。

无需分析绝对数据,而是分析从一个数据点到下一个数据点的变化量。

这是需要的一个快速班轮;分离数据作为输入,并输出该数据的增量。

perl -0x3b -ple'( $last, $_ ) = ( $_, $_-$last )' < test.in > test.out

在您提供的数据上运行它,这是输出:

0; 0; 20; 0; 0; -1; -1; -1; 0; 0; 0; 0; -1; 0; 0; 0; 0; 0; 1; 0; 1; 1; 1; 1; 1; 1; 0; 0; 2; 0; -2; -1; -2; -1; -2; -1; 0; -2; -1; 1; -1; 0;- 1; 0; 0; 0; 0; -1; 0; -1; 2; 4; 6; 9; 7; 7; 6; -4; -6; -8; -7; -5; -4; 0; -1; 0;- 1; 1; 1; 0; 1; 0; -1; 1; 0; 0; 0; 0; 0; 0; -1; 0; 1; 1; -1; 0; 1; 0; 0; 0 ; 1; 0; -1; 1; 2; 2; 0; 1; 1; 1; 1; 1; 1; 1; 0; 0; 1; 0; 0; -1; -2; -1; -2; -2; -2; -2 ; 0; -1; -1; 0; -1; 0; -1; 0; -1; 0; 1; -1; 0; 0; 0; 0; 0; 0; 0; -1; 1; 1; 0; 0; 0; 0; 0; 0; 0; 0; -1; 1; -1; 0; 0; 1; 0; 0; 0; 0; 0; 0; 0; -1; 1; 0; 0; 0; 0 ; -1; 0; 0; 0; 0; 1; 0; 1; 1; 0; 1; 0; 0; 1; 1; 1; 0; 0; 0; -1; -1; -2;- 1; 0; -2; 0; -1; 0; -1; 0; 1; -1; 0; 0; -1; 0; 0; 0; 1; 5; 5; 7; 8; 9; 4; -7; -5; -8 ; -7; -6; -2; -1; 0; 0; 0; 0; 0; 1; 0; 0; 1; -1; 0; 1; 0; -1; 1; 0; 0; 0 ; 1; 0; 0; 0; 1; 0; 1; 0; 0; 0; 1; 1; 0; 2; 1; 1; 1; 1; 1; 1; 1; 1; 1; -1; 1; 0; 0; -1; -2; -2; -2; -2; -1; 0; -1; -2; -1; 0; -1; -1; 0; 1; -1; 1; 0; -1; 1; -1; 1; 0; -1; 0; 0; 0; -1; 1; 0; 0; 1; 0; -1; 0; 1; 0; 0; 1; -1; 0; -1; 1; 0; -1; 0; 0 ; 0; 0; 1; -1; 0; 1; -1; 0; 0; 0; 0; 0; 0; 1; -1; 0; 1; 0; 0; 2; 0; 1; 0; 1; 1; 1; -1; 0; -2; 0; -1; -2; 0; -1; -1; -2; -1; 0; 0; 0; 0; 0; 0; 0; 0; -1; 0; 0; 4; 3; 9; 8; 11; 4; -5; -6; -8; -8; -4; -2; -2; 0; 0; 0; -1; 1; 0; 0; 1; 0; 0; 1; -1; 0; 1; 0; 0; 0; 1; -1; 0; 1; 1; 0; 0; 0; 0; 1; 0; 1; 0; 1; 2; 1; 1; 2; 0; 1 ; 1; 1; 1; 0; 0; 1; 1; 0; 0; -35; 0; 0; 0;

在上面的文本中插入了换行符,这些换行符最初并不出现在输出中。


完成此操作后,找到qrs复合体就变得很简单了。

perl -F';' -ane'@F = map { abs($_) > 2 and $_ } @F; print join ";", @F'< test.out

;; 20 ;;;;;;;;;;;;;;;;;;; ;;; 4; 6; 9; 7; 7; 6; -4; -6; -8; -7; -5; -4;
;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;; ;;;;;;;; 5; 5; 7; 8; 9; 4; -7; -5; -8; -7; -6
;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;; ;;;;;;;;; 4; 3; 9; 8; 11; 4; -5; -6; -8; -8; -4;
;;;;;;;;;;;;;;;;;-;-35 ;;;

20-35数据点是从原始数据开始的,以0开始和结束。

要查找其他数据点,您将不得不依靠模式匹配。


如果查看第一个p波,则可以清楚地看到一个模式。

0;0;0;0;0;0;1;0;1;1;1;1;1;1;0;0;2;0;-2;-1;-2;-1;-2;-1;0;-2;-1;1;-1;0;-1;0;0;0;0;
#           \________ up _______/   \________ down _________/

但是,在第二个p波上查看图形并不容易。这是因为第二个被进一步分散

0;0;0;1;0;1;1;0;1;0;0;1;1;1;0;0;0;-1;-1;-2;-1;0;-2;0;-1;0;-1;0;1;-1;0;0;-1;0;0;0;
#     \________ up _______/       \________________ down ________________/

第三个P波比其他两个P波更加不稳定。

0;0;0;0;0;1;-1;0;1;0;0;2;0;1;0;1;1;1;-1;0;-2;0;-1;-2;0;-1;-1;-2;-1;0;0;0;0;0;
#                \_______ up ______/  \__________ down __________/

您将以类似于p波的方式找到t波。主要区别是它们何时发生。


这应该是足够的信息,可以帮助您入门。

这两个单缸套仅作为示例,不建议日常使用。

收藏
评论

您可以使用互相关 。取每个模式的模型样本,并将它们与信号相关联。您将在相关性很高的地方获得峰。我希望这种提取qrs和t波的技术能取得良好的效果。之后,您可以通过在qrs之前的相关信号上寻找峰值来提取p波。

互相关是一个非常容易实现的算法。基本上:

x is array with your signal of length Lx
y is an array containing a sample of the signal you want to recognize of length Ly
r is the resulting correlation

for (i=0; i<Lx - Ly; i++){
  r[i] = 0;
  for (j=0; j<Ly ; j++){
    r[i] += x[i+j]*y[j];
  }
}

并寻找r中的峰值(例如,超过阈值的值)

收藏
评论

另外两个尖锐的峰谷也是qrs复合体吗?

我想不到的是,您需要做的是计算此图在每个点的斜率。然后,您还需要查看斜率变化的速度(二阶导数???)。如果您有一个突然的变化,那么您就知道自己已经达到了一个尖峰。当然,您希望限制对变化的检测,因此您可能想要执行类似“如果斜率在时间间隔T内X改变”之类的操作,这样就不会拾取图中的微小颠簸。

自从我做任何数学以来已经有一段时间了...这似乎是一个数学问题;)哦,我也没有进行任何信号分析:)。

只是增加了一点。您也可以尝试平均信号,我认为。例如,平均最后3或4个数据点。我认为您也可以通过这种方式检测到突然的变化。

收藏
评论

一种很可能会产生良好结果的方法是曲线拟合:

  • 将连续波划分为间隔(最好使间隔边界位于qrs络合物的尖峰之间的一半左右)。一次只考虑一个间隔。
  • 定义一个模型函数,可用于近似心电图曲线的所有可能变化。这并不像初看起来那样困难。可以将模型函数构造为三个函数的总和,每个函数的参数分别为每个波的原点(t_),幅度(a_)和宽度(w_)。

      f_model(t) = a_p * f_p ((t-t_p )/w_p) + a_qrs * f_qrs((t-t_qrs)/w_qrs) + a_t * f_t ((t-t_t )/w_t) 

    函数f_p(t)f_qrs(t)f_t(t)是一些简单的函数,可用于对三个波动中的每一个进行建模。

  • 使用拟合算法(例如Levenberg-Marquardt-Algorithm http://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm )确定拟合参数a_p,t_p,w_p,a_qrs,t_qrs,w_qrs,a_t ,t_t,w_t为每个intervall的数据集。

    参数t_p,t_qrs和t_p是您感兴趣的参数。

收藏
评论

我不是这个特定问题的专家,但是我对更广泛的常识不屑一顾:假设您知道QRS复合体(或其他功能之一,但在本示例中将使用QRS复合体)发生在大约固定长度L的固定时间段内。我想知道是否可以将其视为分类问题,如下所示:

  1. 将信号分成长度为L的重叠窗口。每个窗口中都包含或不包含完整的QRS复合信号。
  2. 傅立叶变换每个窗口。您的功能是每个频率下的信号强度。
  3. 在一些手工注释的数据上训练决策树,支持向量机等。
收藏
评论

要做的第一件事是查看那里已经有什么 。确实,这个特定的问题已经被大量研究。这是一些非常简单的方法的简要概述: link

我也必须回答另一个答案。我从事信号处理和音乐信息检索的研究。从表面上看,此问题的确与发作检测相似,但问题背景不同。这种类型的生物信号处理,即P,QRS和T相位的检测,可以利用这些波形中每个波形的特定时域特性的知识。实际上,MIR中的启动检测不是。 (至少不可靠。)

动态时间扭曲是一种对QRS检测(但不一定对音符开始检测)有效的方法。当时域特性保持不变时,DTW可以很好地工作。这是使用DTW解决此问题的简短IEEE论文: link

这是一篇不错的IEEE杂志文章,比较了许多方法: link 。您会看到尝试了许多常见的信号处理模型。略读本文,然后尝试基本了解的内容。

编辑:浏览这些文章后,基于小波的方法对我来说似乎最直观。 DTW也将很好地工作,并且存在DTW模块,但是小波方法对我来说似乎是最好的。有人通过利用信号的导数来回答。我的第一个链接研究的是1990年前的方法,但是我怀疑它们不像更现代的方法那样健壮。

编辑:我会尽力给出一个简单的解决方案,当我得到机会,但为什么我觉得小波在这里适用的原因是因为他们在无论时间还是幅度缩放参数化各种形状的有用。换句话说,如果您的信号具有相同的重复时间形状,但时标和幅度不同,则小波分析仍可以将这些形状识别为相似的(大致而言)。另请注意,我将过滤器库混入此类。类似的事情。

收藏
评论

这个难题的一个部分是“ 发作检测 ”,并且已经编写了许多复杂的算法来解决此问题。这里有更多关于发病的信息。

下一块是汉明距离 。该算法允许您进行模糊比较,输入是2个数组,输出是2个数据集之间的整数“距离”或差。数字越小,2越相似。这非常接近您的需求,但并不完全正确。我继续对汉明距离算法进行了一些修改,以计算新的距离,它可能有一个名称,但我不知道它是什么。基本上,它求和数组中每个元素之间的绝对距离并返回总数。这是python中的代码。

import math

def absolute_distance(a1, a2, length):
       total_distance=0
       for x in range(0,length):
               total_distance+=math.fabs(a1[x]-a2[x])
       return total_distance

print(absolute_distance([1,3,9,10],[1,3,8,11],4))

该脚本输出2,这是这2个数组之间的距离。

现在将这些片段放在一起。您可以使用“开始检测”来找到数据集中所有波的开始。然后,您可以循环这些位置,将每个波与一个样本P波进行比较。如果您打了QRS综合大楼,距离将是最大的。如果您按下另一个P-Wave,该数字将不会为零,但会小得多。任何P波形和任何T波形之间的距离都将很小,但是,如果进行以下假设,这将不是问题:

The distance between any p-wave and any other p-wave will be smaller than the distance between any p-wave and any t-wave.

该系列看起来像这样:pQtpQtpQt ... p波和t波彼此相邻,但是由于此序列是可预测的,因此更易于阅读。

另一方面,可能存在基于微积分的解决方案。但是在我看来,曲线拟合和积分使这个问题更加混乱。我写的距离函数会发现面积差 ,这减去两条曲线的积分非常相似。

可以牺牲开始计算,而一次只迭代1个点,从而执行O(n)距离计算,其中n是图中的点数。如果您拥有所有这些距离计算的列表,并且知道那里有50个pQt序列,那么您将知道50个最短的距离, 这些距离在p波的所有位置都不重叠答对了!为了简单起见,这怎么样?但是,由于距离计算数量的增加,折衷是效率的损失。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号