一维ECG信号分割以及2D图像的转化(一)

MIT-BIH这一数据集在几乎所有的ECG信号相关的论文的实验部分都会提到,大部分对其的处理都是filter,segment,或者是求一下RR_interval这一类时域特征,然后换换model,跑一跑。而且大部分代码都是不开源的。

针对于此,在本篇文章中,1,笔者提供了一个信号分割代码的写作思路。2.提供了一个将一维信号转变为二维信号的代码写作思路。并可由此实现快速的dataset构建。

数据链接如下:

MIT-BIH Database (kaggle.com)

平台:kaggle云平台

开始

遍历数据文件。

fannotation = []
frecording = []
lst = os.listdir('/kaggle/input/mitbih-database')
lst.sort()
for file in lst:
    if file.endswith(".csv"):
        frecording.append(file)
    else:
        fannotation.append(file)
print(frecording)
print(fannotation)

03e324a2ab664e35bb6d68f85746dc1a.png

在kaggle平台上,如果进行大规模的图像生成的话,会有比较可怕的效果(亲身实测)
因此,在这个平台上,我只进行一些小规模的二维图像生成。
下面以100.csv以及100annotations.txt为例

filename_csv = '/kaggle/input/mitbih-database' +'/'+ frecording[0]
test_csv = pd.read_csv(filename_csv)
print(test_csv)

55f3d5989523415c9c6bc1c9c5f815ca.png

#该csv的column打出来好麻烦,换掉。
test_csv.columns = list(range(len(test_csv.columns)))
print(test_csv)

7a335be5836f48c68cb32847fa69b82d.png

处理一下txt文件,将其变成dataframe格式。

filename_txt =os.path.join('/kaggle/input/mitbih-database',fannotation[0])

f = open(filename_txt, 'r')
next(f) # skip first line!,因为第一行是表头。


annotations = []
for line in f:
    tmp_list = line.split()
    annotations.append(tmp_list)
f.close
#第一个元素是波峰在总时间段的时刻,第二个是波峰的在样本中的序号。第三个是label的代号。
print('the data_format example is:',annotations[1])

#把波峰的序号和label提取出来
def slice_label_and_dot(annotations):
    labels = []
    sample_dot = []
    for i in range(len(annotations)):
        labels.append(annotations[i][2])
        sample_dot.append(int(annotations[i][1]))
    return labels,sample_dot


labels,sample_dot = slice_label_and_dot(annotations)

#新建dataframe,表头为位置信息和标签信息。
data_frame = {'sample_dot':sample_dot,'labels':labels}
test_df = pd.DataFrame(data_frame)
print(test_df)

bf295f1f734349c8998253cbb9cc2ab6.png

下面代码的大体思路是这样的,我通过test_df中的波峰位置,找出test_csv(也就是100.csv中的原始信号)中对应的点,用上一个波峰的位置+20,和下一个波峰的位置减20,构成一个序列,把这个序列画出来,用灰度的形式保存,同时将jpg名字,和对应test_df的label信号写进一个csv中,变成大家非常熟悉的filename和label的那种dataframe。 非常容易进行dataset的编写。

import cv2
import sys
import os
def draw_pictures(data_frame,raw_data):
    directory = '/kaggle/working'
    
    labels = []
    file_name = []


    #避免生成太多的图片,平台直接卡死
    #for i in range(1,len(data_frame['labels']-1)):
    for i in range(1,30):
        #把坐标系,框架之类的全部隐藏
        fig = plt.figure(frameon=True)
        labels.append(data_frame['labels'][i])
        plt.plot(raw_data[2][data_frame['sample_dot'][i-1]+20:data_frame['sample_dot'][i+1]-20]) 
        plt.xticks([]), plt.yticks([])
        for spine in plt.gca().spines.values():
            spine.set_visible(False)

        #filename构建,可以把峰值点和label信息藏在名字中,方便后续的查找以及验证
        filename = directory + '/' + str(data_frame['sample_dot'][i])+data_frame['labels'][i]+'.jpg' #.png

        file_name.append(filename)

        #保存图片
        fig.savefig(filename)

        #颜色信息无用,用cv2裁剪,转化为灰度图,再次保存。
        im_gray = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
        im_gray = cv2.resize(im_gray, (128, 128), interpolation = cv2.INTER_LANCZOS4)
        cv2.imwrite(filename, im_gray)


        plt.close()
        
    dataset_frame = {'file_name':file_name,'labels':labels}
    test_dataset_frame = pd.DataFrame(dataset_frame)
    return test_dataset_frame
test_data_frame= draw_pictures(test_df,test_csv)
print(test_data_frame)

1e2db7b4ab6c4a93aa8d4a15110c09e7.png

 转化成了我们喜闻乐见的形式。

 简单看一下生成的图片对不对。

from PIL import Image
img1 = Image.open('/kaggle/working/6527N.jpg') 
img2 = Image.open('/kaggle/working/2044A.jpg') 

fig, axs = plt.subplots(1, 2, figsize=(10, 5))

axs[0].imshow(img1, cmap='gray')
axs[0].axis('off')
axs[0].set_title('Image 1')

axs[1].imshow(img2, cmap='gray')
axs[1].axis('off')
axs[1].set_title('Image 2')

plt.show()

aaba547c8a9041bd86a3633d5a7fd9bd.png

完毕。

这个代码只是提供一个思路,还是有一些缺陷的,比如在filename的命名上,可以做的再标准一点,受限于平台的计算能力,也没有使用一整套代码,一键将所有数据全部转化为我们想要的格式。

等我把剩下的代码整理整理,第二篇就发。

notebook名称:

4a08d2e73c9b43d5ab474f06ca1ddf3c.png

在dataset中的code一栏中很容易找到。欢迎来调试和玩耍。 

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值