使用的代碼和數據:https://download.csdn.net/download/zhoudapeng01/12545345
在做腦波數據分析的時候,免不了需要進行頻率域的數據分析,功率譜密度是常用的一種分析方法,在MNE庫中有psd算法的實現。開始使用之前推薦個博客,https://zhuanlan.zhihu.com/p/49328001 講解了什麼是PSD。有一點需要注意,PSD通常根據頻率分辨率做歸一化也就是其分母爲採樣點數。
本文是以BCI競賽的數據爲例,文章中的數據和代碼如下:
https://download.csdn.net/download/zhoudapeng01/12545345
數據是挑選有效epoch後保存爲fif格式的,有關保存epoch格式的數據詳情見博客https://blog.csdn.net/zhoudapeng01/article/details/103893014
這種方法有一個問題就是隻有繪製的圖像,不能針對相關的數據進行後續處理。實際上mne中還有其他一些細節計算的方法,比如:mne.time_frequency.psd_welch(),mne.time_frequency.psd_multitaper() 等,其在官方的實例中均有體現。這裏以用psd_multitaper計算不同頻率區間的累加和爲例:主要的目的是計算不同事件在不同頻率區間的能量和,這裏只分析一個通道的結果。
import mne
import numpy as np
import matplotlib.pyplot as plt
from mne.time_frequency import psd_multitaper
mne.set_log_level(False)
# 設置分析頻率的區間範圍,這裏有小數主要是爲了和後面小波變換方法做對比(暫時未實現)。
iter_freqs = [
{'name': 'Delta', 'fmin': 0, 'fmax': 3.75},
{'name': 'Theta', 'fmin': 3.75, 'fmax': 7.5},
{'name': 'Alpha', 'fmin': 7.5, 'fmax': 12.5},
{'name': 'Beta', 'fmin': 12.5, 'fmax': 35},
]
# 設置不同事件對應的顏色
color_events = {'cueLeft': (1, 0, 0), 'cueRight': (0, 1, 0), 'cueFoot': (0, 0, 1), 'cueTongue': (1, 1, 0)}
#################psd計算頻率區間的能量分佈(單通道)############
def EpochPSDEnergy(epochs):
# 遍歷epochs中的不同事件
for event in epochs.event_id:
# 計算某個事件對應所有epochs的功率譜密度(返回爲ndarray)
psds, freqs = psd_multitaper(epochs[event], n_jobs=1)
# 計算事件對應epochs的均值
psds = np.squeeze(np.average(psds, axis=0))
#初始化能量矩陣
eventEnergy =[]
# 遍歷不同頻率區間的能量和
for iter_freq in iter_freqs:
eventEnergy.append(np.sum(psds[(iter_freq['fmin'] < freqs) & (freqs < iter_freq['fmax'])]))
# 繪製不同事件、不同頻率區間的能量值
plt.plot([xLabel['name'] for xLabel in iter_freqs], eventEnergy, color=color_events[event], label=event, marker='o', lw=0, ms=5)
# 設置標題
plt.title('PSD_SUM')
# 設置圖例
plt.legend()
# 繪圖顯示
plt.show()
if __name__ == '__main__':
# 讀取篩選好的epoch數據
epochs = mne.read_epochs(r'F:\BaiduNetdiskDownload\BCICompetition\BCICIV_2a_gdf\Train\Fif\A02T_epo.fif')
# 這裏只分析一個通道的psd
epochs.pick(['EEG-Cz']).plot_psd()
# 繪製不同區間的能量分佈
EpochPSDEnergy(epochs.pick(['EEG-Cz']))
只實現了算法,還沒具體分析有什麼規律。。。
PS:實際上Python中的matplotlib中是自帶psd計算方法的,如果不想用mne也可以直接調用matplotlib中的方法。
https://www.osgeo.cn/matplotlib/gallery/lines_bars_and_markers/psd_demo.html