使用Python+TensorFlow2構建基於卷積神經網絡(CNN)的ECG心電信號識別分類(二)


心律失常數據庫

目前,國際上公認的標准數據庫包含四個,分別為美國麻省理工學院提供的MIT-BIH(Massachusetts Institute of Technology-Beth Israel Hospital Database, MIT-BIH)數據庫、美國心臟學會提供的AHA( American heart association,AHA)數據庫、歐共體CSE( Common Standards for Quantitative Electrocardiograph,CSE)數據庫、歐洲ST-T數據庫。

當前使用最廣泛且被學術界普遍認可的據庫為MIT-BIH心律失常數據庫。此數據庫中囊括了所有類型的心電信號並且數量豐富,為本文關於心電信號的自動分類研究提供了實驗數據。下面對該數據庫作詳細的說明。
MT-BIH心律失常數據庫擁有48條心電記錄,且每個記錄的時長是30分鍾。這些記錄來自於47名研究對象。這些研究對象包括25名男性和22名女性,其年齡介於23到89歲(其中記錄201與202來自於同一個人)。信號的采樣率為360赫茲,AD分辨率為11比特。對於每條記錄來說,均包含兩個通道的信號。第一個通道一般為MLⅡ導聯(記錄102和104為V5導聯);第二個通道一般為V1導聯(有些為V2導聯或V5導聯,其中記錄124號為Ⅴ4導聯)。為了保持導聯的一致性,往往在研究中采用MLⅡ導聯。本文選取MLⅡ導聯心電信號進行研究分析。

數據庫中的每條記錄均包括三個文件,即:頭文件、數據文件和注釋文件。
(1)頭文件頭文件[.hea] 通過ASCII碼存儲方式記錄信號的采樣頻率、采樣頻率、數據格式使用的導聯信息、采樣頻率、研究者的性別、年齡以及疾病種類等
(2)數據文件數據文件[.dat] 通過二進制的方式存儲信號,每三個字節存儲兩個數值(兩導聯數據交替存儲),每個數值大小是12bit
(3)注釋文件注釋文件[.atr] 是由專家對信號進行人工標注,並且根據二進制格式進行數據的存儲

關於MIT-BIH數據庫的一些常用網站

官方網站請選擇mitdb數據庫

統一術語稱呼

我在閱讀心電相關論文的時候,常常由於不同文章之間對同一事物的稱呼不同而感到困擾。為避免在本文中出現類似情況,現將術語稱呼統一如下。

  • 一條心電數據(記錄、信號):將編號為100,101...的數據稱為一條心電數據(記錄),包含了該編號中的所有導聯數據。由於本文僅使用MLII導聯的數據作為深度學習的訓練數據,因此在本文中也特指一條心電數據中的MLII導聯部分。
  • 心拍:如文章(一)中圖片所示,將一個完整的心電波形稱為一個心拍。
  • 信號點(值):連續的心電波形圖其實是由一系列頻率固定的不連續采樣點構成的,將每個采樣點稱為信號點(值)。

心電數據的讀取

下載數據庫到本地后打開,你會發現.dat文件中全部都是亂碼,這是由於MIT-BIH數據庫采用了自定義的format212格式進行編碼。所以在讀取心電數據的時候,我們需要用到Python中的一個工具包:wfdb。

在Pycharm中新建工程,並將下載好的心電數據集按如圖所示的目錄結構進行放置。其中ecg_data為心電數據集的文件夾。

Snipaste_2020-05-05_12-31-06

在該工程配置的Python環境中安裝wfdb包。

pip install wfdb

關於wfdb包的詳細使用請參考其官方文檔,這里用代碼的形式給出一些常用操作。

# 讀取編號為data的一條心電數據
def read_ecg_data(data):
    '''
    讀取心電信號文件
    sampfrom: 設置讀取心電信號的起始位置,sampfrom=0表示從0開始讀取,默認從0開始
    sampto:設置讀取心電信號的結束位置,sampto = 1500表示從1500出結束,默認讀到文件末尾
    channel_names:設置設置讀取心電信號名字,必須是列表,channel_names=['MLII']表示讀取MLII導聯線
    channels:設置讀取第幾個心電信號,必須是列表,channels=[0, 3]表示讀取第0和第3個信號,注意信號數不確定
    '''
    # 讀取所有導聯的信號
    record = wfdb.rdrecord('../ecg_data/' + data, sampfrom=0, sampto=1500)
    # 僅僅讀取“MLII”導聯的信號
    # record = wfdb.rdrecord('../ecg_data/' + data, sampfrom=0, sampto=1500, channel_names=['MLII'])
    # 僅僅讀取第0個信號(MLII)
    # record = wfdb.rdrecord('../ecg_data/' + data, sampfrom=0, sampto=1500, channels=[0])

    # 查看record類型
    print(type(record))
    # 查看類中的方法和屬性
    print(dir(record))

    # 獲得心電導聯線信號,本文獲得是MLII和V1信號數據
    print(record.p_signal)
    print(np.shape(record.p_signal))
    # 查看導聯線信號長度,本文信號長度1500
    print(record.sig_len)
    # 查看文件名
    print(record.record_name)
    # 查看導聯線條數,本文為導聯線條數2
    print(record.n_sig)
    # 查看信號名稱(列表),本文導聯線名稱['MLII', 'V1']
    print(record.sig_name)
    # 查看采樣率
    print(record.fs)

    '''
    讀取注解文件
    sampfrom: 設置讀取心電信號的起始位置,sampfrom=0表示從0開始讀取,默認從0開始
    sampto:設置讀取心電信號的結束位置,sampto=1500表示從1500出結束,默認讀到文件末尾
    '''
    annotation = wfdb.rdann('../ecg_data/' + data, 'atr')
    # 查看annotation類型
    print(type(annotation))
    # 查看類中的方法和屬性
    print(dir(annotation))

    # 標注每一個心拍的R波的尖鋒位置的信號點,與心電信號對應
    print(annotation.sample)
    # 標注每一個心拍的類型N,L,R等等
    print(annotation.symbol)
    # 被標注的數量
    print(annotation.ann_len)
    # 被標注的文件名
    print(annotation.record_name)
    # 查看心拍的類型
    print(wfdb.show_ann_labels())

    # 畫出數據
    draw_ecg(record.p_signal)
    # 返回一個numpy二維數組類型的心電信號,shape=(65000,1)
    return record.p_signal

在這些函數中,使用最多的是通過record=wfdb.rdrecord來獲取心電數據信息,以及通過annotation=wfdb.rdann來獲取心拍類型信息。需要注意的是record的類型是一個(65000,1)的二維數組,需要先將其轉換成一維數組才可以對其進行預處理,關於預處理的這部分內容將在下篇文章中進行敘述。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM