简单的DIY心率监测心电图显示

Mary-Kate Olsen
发布: 2024-10-18 06:15:30
原创
658 人浏览过

目标
这个迷你项目/教程的目标是用最少的组件制作一个超级简单的心率监视器和滚动心电图显示。

要求:

  • 蟒蛇
  • 音频接口
  • 1/4英寸连接线/吉他线/乐器线(只需通过音频接口接入电脑即可)

快速背景

心脏的肌肉产生电信号。其中一些信号可以在皮肤表面检测到。

我们可以使用表面电极拾取这些信号。问题是,这些并不是皮肤上唯一的电信号。值得庆幸的是,我们想要看到的大多数信号都限制在 1-40Hz 左右。

流程

我们将把我们的 1/4" 电缆作为我们的电极,将其插入心脏附近的皮肤。然后我们使用 USB 音频接口来放大模拟信号并将其转换为数字信号.最后我们在python中进行过滤和显示

步骤

第 1 步: 1/4 英寸电缆由两部分组成:套管和尖端。这两个部分都需要与您的皮肤接触 - 只需用手握住套管并将其压在胸部/上肋骨的左侧(某些电缆可能有更多通道,只需确保它们都已接触即可启动)。调整音频接口的增益(我将我的一直调高)。

Simple DIY HR Monitor ECG Display

第 2 步: 运行以下代码。 确保检查 input_device_index 行是否指向您的音频接口。我们正在做的是获取传入音频的块,使用 fft 转换到频域,将所有不必要的频率设置为 0,然后转换回时域。接下来,我们找到峰值来计算 HR,然后以滚动的方式绘制图表。

import numpy as np 
import pyaudio as pa 
import struct 
import matplotlib.pyplot as plt 
from scipy.signal import decimate, find_peaks

CHUNK = 4410 #.1 second
FORMAT = pa.paInt16
CHANNELS = 1
RATE = 44100 # in Hz
fstep = RATE/CHUNK
p = pa.PyAudio()

values = []
dsf=44 #down sample factor
rds=RATE/dsf #down sampled rate

stream = p.open(
    format = FORMAT,
    channels = CHANNELS,
    rate = RATE,
    input_device_index=3, #adjust based on input
    input=True,
    frames_per_buffer=CHUNK
)

#set up graph
fig,ax = plt.subplots(1)
x = np.arange(0,2*CHUNK,2)
line, = ax.plot(x, np.random.rand(CHUNK))
ax.set_ylim(-100,100) 
ax.set_xlim(0,2500) 
text = ax.text(0.05, 0.95, str(0), transform=ax.transAxes, fontsize=14,
       verticalalignment='top')
fig.show()

def getFiltered(x,hp=1,lp=41): #this sets the unneeded freqs to 0

    fft=np.fft.fft(x)
    hptrim=len(fft)/RATE*hp
    lptrim=len(fft)/RATE*lp
    fft[int(lptrim):-int(lptrim)]=0 
    fft[0:int(hptrim)]=0 
    return np.real(np.fft.ifft(fft))

def getHR(x): 

    pdis = int(0.6 * rds) #minimum distance between peaks. stops rapid triggering. also caps max hr, so adjust
    peaks, _ = find_peaks(x, distance=pdis, height=0.1)
    intervals = np.diff(peaks)/rds # in seconds
    hr = 60 / intervals # in BPM
    return peaks,round(np.mean(hr),0) #peaks,avg hr

while 1:
    data = stream.read(CHUNK)
    dataInt = struct.unpack(str(CHUNK) + 'h', data)

    filtered=getFiltered(dataInt) #filter (working with full chunk)
    dsed=decimate(filtered, 44) #down sample (turns chunk into ds chunk)
    values=np.concatenate((values,dsed)) #puts the chunks into an array
    peaks,hr = getHR(values*-1) # gets the peaks and determins avg HR. 

    text.set_text(str(hr))
    line.set_xdata(np.arange(len(values))) 
    line.set_ydata(values*-10) #the negative is bc it comes in upside down with my set up. the *10 is just for fun
    ax.set_xlim(max(0,len(values)-2500),len(values)) #keep the graph scrolling
    vlines = ax.vlines(peaks,ymin=-100,ymax=100,colors='red', linestyles='dashed') # pop some lines at the peaks 

    fig.canvas.draw()
    fig.canvas.flush_events()
    vlines.remove()

    if len(values)>10000: #keeps the array managably sized, and graph scrolling pretty
        values=values[5000:] #5 seconds @ ~1000 sr.

登录后复制

笔记
保持电缆不动 - 您可能需要在运动后等待几秒钟才能获得准确的心率。我对照我的 Garmin 手表检查了它,它始终返回相似的值。

输出
Simple DIY HR Monitor ECG Display

免责声明
请记住,从技术上讲,您正在使您的身体成为电路的一部分。电缆连接到连接到计算机的接口,该计算机连接到墙壁电源插座...尝试此操作需要您自担风险。我不是专家 - 我只是喜欢摆弄东西,并想分享。

后续步骤
这种方法对于清楚地看到心电图信号的所有不同部分来说并不能很好地发挥作用。电极非常磨损,我只做了最低限度的过滤。

它在检测肌电图等较小信号方面也表现不佳。

从这里您可以在软件方面进行更深入的挖掘并使用其他滤波器,或者创建实际的电路并使用真实的电极。用于此类物品的一袋电极在亚马逊上非常便宜(注意,粘合剂很烦人)。对于电路,我尝试了几种不同的配置 - 我发现最简单/最适合我的是使用 JFET 运算放大器的简单仪表放大器电路(放在面包板上)。 3个电极,只需查一下图表即可知道放置位置。如果您使用 ADC 的音频接口,此处的代码应与设置的 3 电极面包板配合使用(可能需要调整增益)

为什么
这个迷你项目的灵感来自于拿着吉他线在 DAW 中使用 EQ 插件时的感受。

以上是简单的DIY心率监测心电图显示的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!