Unet心电信号分割方法(Pytorch)

心血管疾病是一种常见病,严重影响人们的健康及日常生活。 近年来随着人们生活习惯的不断变化,心血管疾病对人们影响愈加明显,发病率呈现出逐年攀升的趋势,心血管疾病是中国城乡居民死亡的首要原因。心电图ECG已被广泛用于研究心跳活动。作为一种无创的方法,ECG的相关研究为了解心脏的功能提供了便利。对心电图进行有效分析可以为心血管疾病的诊断和防治提供丰富的信息,进而大大减缓心血管疾病对人们生活的影响。

心电信号分割是心电图解读的第一步,通过心电信号分割,有助于进一步对运动员心脏健康状况进行分析,进而减少运动员受伤、致病及运动中猝死的风险。

from typing import Union,List, Tuple
# get signal with wfdb library# using an indexdef get_signal(index:int, as_p_signal:bool=True) -> Union[wfdb.Record, np.ndarray]:    record = wfdb.rdrecord(DATA_FOLDER + "/" +  str(index))    assert type(record) is wfdb.Record
    if as_p_signal:        assert type(record.p_signal) is np.ndarray        return record.p_signal            return record
# get annotations given the ecg leaddef get_annotations(index:int, lead, as_sample=True) -> Union[wfdb.Annotation, np.ndarray]:    annotations = wfdb.rdann(DATA_FOLDER +"/" + str(index), extension = lead)    if as_sample:        return np.array(annotations.sample)    return annotations
# get a full EGC with 12 leadsdef get_full_ecg(index:int):    signal = get_signal(index)    annotations = [        get_annotations(index, lead) for lead in LEADS    ]    return signal, annotationsdef get_single_lead_ecg(index, lead) -> Tuple[np.ndarray, np.ndarray]:    """    return and ecg signal and its annotations    both as ndarray    """    signal = get_signal(index)    assert type(signal) is np.ndarray    signal = signal[:, LEADS.index(lead)]
    samples = get_annotations(index, lead)    assert type(samples) is np.ndarray        return signal, samplesdef get_annotations_symbols(index, lead):    ann = get_annotations(index, lead, as_sample=False)    return ann.symbol
def paired_annotation_sample_and_symbol(index, lead):    annotations_symbols = get_annotations_symbols(index, lead)    annotations_sample = get_annotations(index, lead)    return zip(annotations_sample, annotations_symbols)def get_single_lead_ecg_with_symbols(index, lead):    """    return and ecg signal and its annotations    both as ndarray    """    signal = get_signal(index)    assert type(signal) is np.ndarray    signal = signal[:, LEADS.index(lead)]
    data = paired_annotation_sample_and_symbol(index, lead)        return signal, np.array(list(data))
# plot single lead ecg with annotationsdef plot_single_lead_ecg(index, lead):    signal, samples = get_single_lead_ecg(index, lead)
    fig, ax = plt.subplots(figsize = (28, 3))
    ax.plot(signal)    ax.scatter(samples, signal[samples], c = 'r', marker = 'o')# now plot every lead with annotationsdef plot_signal_with_annotation(index):    signal, samples = get_full_ecg(index)    # extract sample from annotations    wfdb.plot_items(signal, samples )
plot_signal_with_annotation(index = 199)

图片

class EGCSignal:    """    This class has 4 main purposes:    1. To store the signal and its annotations    2. To cut the signal once at the beginning and once at the end    3. To plot the ECG in different ways    4. To convert the annotation in a one hot encoding
    Note that doesn't store the entire ECG, but only one lead
    Also has a method to initialize the class without explicitly passing the signal and annotations    but with the index and lead of the record    """    def __init__(self, signal, time_points, symbol, categories = None):        self.signal:np.ndarray = signal        self.time_points:np.ndarray = time_points        self.symbols:list[str] = symbol        self.symbol_to_category = {            'N': 0,            't': 1,            'p': 2        }        self.category_to_symbol = {            0: 'N',            1: 't',            2: 'p'        }        self.categories = categories if categories is not None else self.symbols_to_category()        self._cut_beginning( 550)        self._cut_end( 3500)
    def __getitem__(self, key):        return self.signal[key]
    def __len__(self):        return len(self.signal)
    def _cut_beginning(self, start_point):        self.signal = self.signal[start_point:]        self.categories = self.categories[start_point:]
        # now have to check if time_points and symbols are also to cut        if start_point > self.time_points[0]:            # get the index of the first time point greater than start_point            index = np.argmax(self.time_points > start_point)                            self.time_points = self.time_points[index:]            self.symbols = self.symbols[index:]
        self.time_points = self.time_points - start_point
        # check the cut point        if self.categories[0] != -1:            # if the first symbol is a ')' then i have to prepend a '(' and a letter from self.category_to_symbol            if self.symbols[0] == ')':                self.symbols = ['('] + [self.category_to_symbol[self.categories[0]]] + self.symbols                self.time_points = np.concatenate(([0,1], self.time_points))            elif self.symbols[0] in self.symbol_to_category:                # just prepend '('                self.symbols = ['('] + self.symbols                self.time_points = np.concatenate(([0], self.time_points))
    def _cut_end(self, end_point):        self.signal = self.signal[:end_point]        self.categories = self.categories[:end_point]
        index = self.time_points[self.time_points < self.signal.size].size        self.time_points = self.time_points[:index]        self.symbols = self.symbols[:index]
        # check the cut point        if self.categories[-1] != -1:            # if the last symbol is a '(' then i have to append a ')' and a letter from self.category_to_symbol            if self.symbols[-1] == '(':                self.symbols = self.symbols +  [self.category_to_symbol[self.categories[-1]]] + [')']                self.time_points = np.concatenate((self.time_points, [self.signal.size - 1, self.signal.size ]))            elif self.symbols[-1] in self.symbol_to_category:                # just append ')'                self.symbols = self.symbols + [')']                self.time_points = np.concatenate((self.time_points, [self.signal.size]))     def plot(self, ax=None):        if ax is None:            fig, ax = plt.subplots(figsize = (28, 3))        ax.plot(self.signal)
    def plot_with_time_point(self):        fig, ax = plt.subplots(figsize = (28, 3))        self.plot(ax)        ax.scatter(self.time_points, self.signal[self.time_points], c = 'r', marker = 'o')
    def plot_with_segments(self):        fig, ax = plt.subplots(figsize = (28, 3))        self.plot(ax)
        for start, symbol, end in grouped(self.time_points, 3):                        i = np.nonzero(self.time_points == symbol)[0][0]            current_symbol = self.symbols[i]            color = SEGMENT_TO_COLOR[current_symbol]            ax.axvspan(start, end, color=color, alpha=0.4)
    def symbols_to_category(self):        """        converts the symbols list in a numpy array of integers        same length as the signal        """
        # first instantiate an array of -1 same length as the signal        category = np.full(len(self.signal), -1)        # now fill the array with the known category        for section in grouped(self.time_points):            # unpack the section            start, peak, end = section                                    # get the category given the peak            i = np.nonzero(self.time_points == peak)[0][0]            current_symbol = self.symbols[i]
            category[start:end] = self.symbol_to_category[current_symbol]
        return category
    @staticmethod    def from_index_and_lead(index, lead):        return EGCSignal(        get_signal(index)[:, LEADS.index(lead)],        get_annotations(index, lead),        get_annotations_symbols(index, lead) )EGCSignal.from_index_and_lead(1, LEADS[0]).plot_with_segments()

图片

# plot categories on ecgsignal = X_test[ecg_index]categories = np.argmax(Y_test[ecg_index], axis=1)predicted_categories = np.argmax(Y_test_pred[ecg_index], axis=1)
# get time point where category changestime_points = np.where(categories[:-1] != categories[1:])[0]
# chek if category was at beginning or endif categories[0] != 0:    # if category was at beginning, add first time point    time_points = np.append(0, time_points)if categories[-1] != 0:    # if category was at end, add last time point    time_points = np.append(time_points, len(categories))
# plot the signalplt.figure(figsize=(10, 4))plt.plot(signal)for b,e in grouped(time_points, 2):    plt.axvspan(b, e, facecolor='0.5', alpha=0.5)

图片

signal = X_test[ecg_index]categories = np.argmax(Y_test[ecg_index], axis=1)predicted_categories = np.argmax(Y_test_pred[ecg_index], axis=1)
# get time point where category changestime_points = np.where(predicted_categories[:-1] != predicted_categories[1:])[0]# chek if category was at beginning or endif predicted_categories[0] != 0:    # if category was at beginning, add first time point    time_points = np.append(0, time_points)if predicted_categories[-1] != 0:    # if category was at end, add last time point    time_points = np.append(time_points, len(predicted_categories))
# plot the signalplt.figure(figsize=(10, 4))plt.plot(signal)for b,e in grouped(time_points, 2):    plt.axvspan(b, e, facecolor='0.5', alpha=0.5)

图片

plt.figure(figsize=(10, 4))
plt.plot(signal, color = "gray")plt.plot(pred[:,0]*signal, alpha=0.5) # predicted not interesting
plt.plot(pred[:,3]*signal, alpha=0.9, label= "p", c=SEGMENT_TO_COLOR['p']) # predicted p
plt.plot(pred[:,1]*signal, alpha=0.9, label= "qrs", c=SEGMENT_TO_COLOR['N']) # predicted qrsplt.plot(pred[:,2]*signal, alpha=0.9, label= "t", c=SEGMENT_TO_COLOR['t']) # predicted t
plt.legend(    loc='upper right',    ncol=1,
)

图片

from matplotlib.collections import LineCollectionfrom matplotlib.colors import ListedColormap
x   = np.arange(len(signal)) t = np.linspace(0,1,x.shape[0]) # your "time" variable
lightblue  = [(0.3, 0.5, 0.9, 0.99 * p) for p in pred[:,1]]lightred   = [(0.99, 0.6, 0.5, 0.99 * p) for p in pred[:,2]]lightgreen = [(0.55, 0.99, 0.66, 0.99 * p) for p in pred[:,3]]# set up a list of (x,y) pointspoints = np.array([x,signal]).transpose().reshape(-1,1,2)segs = np.concatenate([points[:-1],points[1:]],axis=1)
# make the collection of segmentslcblue = LineCollection(segs, cmap=ListedColormap( lightblue))lcblue.set_array(t)lcred = LineCollection(segs, cmap=ListedColormap( lightred))lcred.set_array(t)lcgreen = LineCollection(segs, cmap=ListedColormap( lightgreen))lcgreen.set_array(t)# plot the collectionplt.figure(figsize=(15, 5))plt.plot(signal, alpha = 0.4, linewidth = 2, color='gray')plt.gca().add_collection(lcblue) # add the collection to the plotplt.gca().add_collection(lcred) # add the collection to the plotplt.gca().add_collection(lcgreen) # add the collection to the plotplt.xlim(x.min(), x.max()) # line collections don't auto-scale the plotplt.ylim(signal.min(), signal.max())

图片

工学博士,担任《Mechanical System and Signal Processing》《中国电机工程学报》《控制与决策》等期刊审稿专家,擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/27472.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

光学雨量监测站:科技赋能,精准监测降水过程

TH-YJ3随着科技的不断进步&#xff0c;光学雨量监测站作为一种先进的降水监测设备&#xff0c;正逐渐在气象、水文、农业等领域发挥重要作用。光学雨量监测站以其高精度、高可靠性、实时性强的特点&#xff0c;为降水数据的收集和分析提供了强有力的支持&#xff0c;为相关领域…

Nginx负载均衡之长连接负载均衡

当客户端通过浏览器访问 HTTP 服务器时&#xff0c;HTTP 请求会通过 TCP 协议与 HTTP 服务器建立一条访问通道&#xff0c;当本次访问数据传输完毕后&#xff0c;该 TCP 连接会立即被断开&#xff0c;由于这个连接存在的时间很短&#xff0c;所以 HTTP 连接也被称为短连接。 …

Lua实现自定义函数面向对象编程

本文目录 1、引言2、原理3、实例4、层析验证 文章对应视频教程&#xff1a; 暂无&#xff0c;可以关注我的B站账号等待更新。 点击图片或链接访问我的B站主页~~~ 1、引言 在现代软件开发中&#xff0c;面向对象编程&#xff08;OOP&#xff09;已经成为一种广泛使用的编程范式…

俄罗斯Yandex推广投放如何开户?Yandex广告开户和代运营推广流程详解_俄罗斯_受众_搜索引擎

在俄罗斯进行Yandex广告推广是一种有效的在线营销方式&#xff0c;特别是针对俄罗斯市场。Yandex是俄罗斯最受欢迎的搜索引擎&#xff0c;类似于Google在全球范围内的地位。以下是通过Yandex广告推广的一般步骤&#xff0c;以及如何通过上海上弦进行广告开户和代运营。 1. Yan…

怎么图片转excel表格?推荐三个方法

怎么图片转excel表格&#xff1f;在信息化高速发展的今天&#xff0c;图片转Excel表格的需求日益凸显&#xff0c;尤其是在职场办公中&#xff0c;这一需求更是显得尤为迫切。为了满足广大用户的需求&#xff0c;市面上涌现出了众多图片转Excel的软件。今天&#xff0c;就为大家…

Git 基础操作(一)

Git 基础操作 配置Git 安装完Git后&#xff0c;首先要做的事情是设置你的 用户名 和 e-mail 地址。这样在你向仓库提交代码的时候&#xff0c;就知道是谁提交的&#xff0c;以及提交人的联系方式。 配置用户名和邮箱 使用git config [--global] user.name "你的名字&qu…

Windows如何找回永久删除的文件?完整教程看完即会!

可以找回永久删除的文件&#xff1f; 你是否也在Windows 10中永久删除过文件&#xff1f;什么是永久删除&#xff1f;通常有5种方法可以永久删除文件&#xff1a; 正常删除文件&#xff0c;然后在回收站中再次删除。使用命令提示符&#xff1a;“del”删除文件。使用“ShiftD…

RS485和CAN电路中的TVS管选择

在RS485和CAN电路设计中&#xff0c;经常要考虑“静电和浪涌保护”&#xff0c;怎么选择TVS管&#xff0c;很少有人讲解。 1、先了解TVS管 TVS管有单向管和双向管&#xff0c;通常后缀为CA的是双向TVS管&#xff0c;只有字母A的是单向TVS管。见下图&#xff1a; 2、TVS选择依…

【LLM之RAG】Adaptive-RAG论文阅读笔记

研究背景 文章介绍了大型语言模型&#xff08;LLMs&#xff09;在处理各种复杂查询时的挑战&#xff0c;特别是在不同复杂性的查询处理上可能导致不必要的计算开销或处理不足的问题。为了解决这一问题&#xff0c;文章提出了一种自适应的查询处理框架&#xff0c;动态选择最合…

4天掌握一门新技能是一种什么样的体验?

你能想象这门技术覆盖面有多广吗&#xff1f; 从地产中介到教育培训&#xff0c;从生产制造业到政府企事业、从消费生活到智慧文旅....这门技术都可以为这些行业提供服务。这就是今天要介绍的——VR全景 投入成本有多高&#xff1f; 放在以前&#xff0c;可能还不会推荐&#x…

大规模装箱问题:蜣螂优化算法DBO求解二维装箱问题(MATLAB代码)

一、问题描述 装载率:所有选择的箱子的总面积与夹板面积之比 假设一共有300个箱子&#xff0c;如何设计算法&#xff0c;使得选择部分箱子放入80*80的甲板上&#xff0c;让甲板的装载率越大&#xff0c;要求箱子间不得重叠。 二、蜣螂优化算法求解二维装箱问题 蜣螂优化算法…

Docker中部署Jenkins+Pipline流水线基础语法入门

场景 DockerCompose中部署Jenkins&#xff08;Docker Desktop在windows上数据卷映射&#xff09;&#xff1a; DockerCompose中部署Jenkins&#xff08;Docker Desktop在windows上数据卷映射&#xff09;-CSDN博客 DockerComposeJenkinsPipeline流水线打包SpringBoot项目(解…

next.js v14 升级全步骤|迁移 pages Router 到 App Router

【概括】本文升级整体按照官网文档指引进行&#xff0c;在迁移 pages Router 前先看了官网的实操视频。 【注意】文章内对 .babel.ts、next.config.js 进行了多次更改&#xff0c;最终配置可见 报错3: Server Error ReferenceError: React is not defined 一、升级 Next.js 版…

Pytorch 卷积神经网络-手写数字识别

卷积神经网络是深度学习中的一个里程碑式的技术&#xff0c;有了这个技术&#xff0c;才会让计算机有能力理解图片和视频信息&#xff0c;才会有计算机视觉的众多应用。 本文讨论卷积神经网络模型&#xff08;CNN&#xff09;的Hello World。前面讨论的是一个二分类问题&#x…

网络安全 - DNS劫持原理 + 实验

DNS 劫持 什么是 DNS 为什么需要 DNS D N S \color{cyan}{DNS} DNS&#xff08;Domain Name System&#xff09;即域名系统。我们常说的 DNS 是域名解析协议。 DNS 协议提供域名到 IP 地址之间的解析服务。计算机既可以被赋予 IP 地址&#xff0c;也可以被赋予主机名和域名。用…

Hbase搭建教程

Hbase搭建教程 期待您的关注 ☀小白的Hbase学习笔记 目录 Hbase搭建教程 1.上传hbase的jar包并解压 2.重新登录 3.启动zookeeper 4.配置环境变量 5.关闭ZK的默认配置 6.修改hbase-site.xml文件 7.修改regionservers文件 8.将配置好的文件分发给其它节点 9.配置环境变量…

单通道触摸感应开关RH6016

1.简介 SOT23-6 RH6016 封装和丝印 RH6016 是一款内置稳压模块的单通道电容式触摸感应控制开关IC&#xff0c;可以替代传统的机械式开关。 RH6016可在有介质(如玻璃、亚克力、塑料、陶瓷等)隔离保护的情况下实现触摸功能&#xff0c;安全性高。 RH6016内置高精度稳压、上电复…

Requests —— 请求头设置!

前戏 在我们进行自动化测试的时候&#xff0c;很多网站都会都请求头做个校验&#xff0c;比如验证 User-Agent&#xff0c;看是不是浏览器发送的请求&#xff0c;如果我们不加请求头&#xff0c;使用脚本访问&#xff0c;默认User-Agent是python&#xff0c;这样服务器如果进行…

DeepSORT(目标跟踪算法)卡尔曼滤波中的贝叶斯定理

DeepSORT&#xff08;目标跟踪算法&#xff09;卡尔曼滤波中的贝叶斯定理 flyfish 从例子中介绍名词 假设我们有一个袋子&#xff0c;里面有5个红球和3个蓝球。我们从袋子里随机抽取一个球。 概率 (Probability) 我们想计算从袋子里抽到红球的概率 P ( R ) P(R) P(R)。 …

misc刷题记录(1)陇剑杯

[陇剑杯 2021]签到 题目内容&#xff1a;此时正在进行的可能是__________协议的网络攻击。&#xff08;如有字母请全部使用小写&#xff0c;填写样例&#xff1a;http、dns、ftp&#xff09;。得到的flag请使用NSSCTF{}格式提交。 打开统计&#xff0c;找到协议分级&#xff…