脑电EEG代码开源分享 【1.前置准备-静息态篇】
往期文章
希望了解更多的道友點(diǎn)這里
0. 分享【腦機(jī)接口 + 人工智能】的學(xué)習(xí)之路
1.1 . 腦電EEG代碼開源分享 【1.前置準(zhǔn)備-靜息態(tài)篇】
1.2 . 腦電EEG代碼開源分享 【1.前置準(zhǔn)備-任務(wù)態(tài)篇】
2.1 . 腦電EEG代碼開源分享 【2.預(yù)處理-靜息態(tài)篇】
2.2 . 腦電EEG代碼開源分享 【2.預(yù)處理-任務(wù)態(tài)篇】
3.1 . 腦電EEG代碼開源分享 【3.可視化分析-靜息態(tài)篇】
3.2 . 腦電EEG代碼開源分享 【3.可視化分析-任務(wù)態(tài)篇】
4.1 . 腦電EEG代碼開源分享 【4.特征提取-時(shí)域篇】
4.2 . 腦電EEG代碼開源分享 【4.特征提取-頻域篇】
4.3 . 腦電EEG代碼開源分享 【4.特征提取-時(shí)頻域篇】
4.4 . 腦電EEG代碼開源分享 【4.特征提取-空域篇】
5 . 腦電EEG代碼開源分享 【5.特征選擇】
6.1 . 腦電EEG代碼開源分享 【6.分類模型-機(jī)器學(xué)習(xí)篇】
6.2 . 腦電EEG代碼開源分享 【6.分類模型-深度學(xué)習(xí)篇】
匯總. 專欄:腦電EEG代碼開源分享【文檔+代碼+經(jīng)驗(yàn)】
0 . 【深度學(xué)習(xí)】常用網(wǎng)絡(luò)總結(jié)
腦電EEG代碼開源分享 【1.前置準(zhǔn)備-靜息態(tài)篇】
- 往期文章
- 一、前言
- 二、前置準(zhǔn)備 框架介紹
- 三、代碼格式說明
- 三、腦電處理 代碼
- 3.0 參數(shù)設(shè)置
- 3.1 數(shù)據(jù)導(dǎo)入
- 3.2 前置準(zhǔn)備-主函數(shù)
- 3.3 前置準(zhǔn)備-功能函數(shù)
- 3.4 前置準(zhǔn)備-結(jié)果保存
- 四、前置準(zhǔn)備 整體代碼
- 總結(jié)
- To:新想法、鬼點(diǎn)子的道友:
一、前言
本文檔旨在歸納BCI-EEG-matlab的數(shù)據(jù)處理代碼,作為EEG數(shù)據(jù)處理的總結(jié),方便快速搭建處理框架的Baseline,實(shí)現(xiàn)自動(dòng)化、模塊插拔化、快速化。本文非鎖時(shí)任務(wù)(無鎖時(shí)刺激,如靜息態(tài)、運(yùn)動(dòng)想象)為例,分享腦電EEG的分析處理方法。
腦電數(shù)據(jù)分析系列。分為以下6個(gè)模塊:
1. 前置準(zhǔn)備
2. 數(shù)據(jù)預(yù)處理
3. 數(shù)據(jù)可視化
4. 特征提取(特征候選集)
5. 特征選擇(量化特征擇優(yōu))
6. 分類模型
本文內(nèi)容:【1.前置準(zhǔn)備】
提示:以下為各功能代碼詳細(xì)介紹,若節(jié)約閱讀時(shí)間,請(qǐng)下滑至文末的整合代碼
二、前置準(zhǔn)備 框架介紹
前置準(zhǔn)備
前置準(zhǔn)備的主要功能,分為以下4部分:
1. 降采樣
2. 數(shù)據(jù)分段
3. 去暫態(tài)
4. 選擇導(dǎo)聯(lián)
前期準(zhǔn)備的代碼框圖、流程如下所示:
注:前置準(zhǔn)備 理論上可以歸類到 預(yù)處理階段,本代碼將兩者分開基于以下考慮:
三、代碼格式說明
本文非鎖時(shí)任務(wù)態(tài)(下文以靜息態(tài)代替)范例為:ADHD患者、正常人群在靜息狀態(tài)下的腦模式分類
- 分段代碼名稱:代碼命名為Standard_cut_rest
- 輸入格式:靜息態(tài)為Data的結(jié)構(gòu)體,內(nèi)部為data命名的原始數(shù)據(jù)(通道*總采樣點(diǎn)數(shù))。
- 參數(shù)設(shè)置:**采樣率\單試次時(shí)長(zhǎng)\試次標(biāo)簽\試次位置\頻域去除暫態(tài)時(shí)長(zhǎng)\降采樣(防止數(shù)據(jù)過大導(dǎo)致運(yùn)行和內(nèi)存消耗)
- 處理形式:**EEG數(shù)據(jù)匯總為cell(試次被試數(shù)),每個(gè)cell內(nèi)為(通道數(shù)采樣點(diǎn)數(shù))。按照不同分類的類別放入不同cell,cell自身名稱如下保存格式名稱。例如任務(wù)態(tài)數(shù)據(jù)為{100,1}[16*512],其意為16通道數(shù)據(jù)采集,100試次,單試次為512點(diǎn)數(shù)據(jù)點(diǎn)。
- **保存格式:**單獨(dú)保存?zhèn)€人的名稱為Standard_input_target_xx(被試序號(hào)),總保存文件名稱為Standard_input_target\ nontarget _xx代表被試個(gè)數(shù)。
三、腦電處理 代碼
提示:代碼環(huán)境為 matlab 2018
3.0 參數(shù)設(shè)置
原采樣率 fs_raw=500Hz,降低到 fs_down = 250Hz
一次進(jìn)行10人次的批處理,subject_num = [1;10]
每段數(shù)據(jù)分段長(zhǎng)度為2秒,epoch_length = 2
處理全部導(dǎo)聯(lián)編號(hào)為1-128的電極,perocess_channel = [1 ; 128];
經(jīng)驗(yàn)建議:
- 采樣率降到300Hz以下,目前主流研究認(rèn)為,靜息態(tài)腦電有效頻率<100Hz,根據(jù)腦奎斯特定理,采樣率到200Hz以上即可。采樣率是最影響計(jì)算時(shí)間的參數(shù)之一,尤其影響后期的非線性計(jì)算,繪圖、特征分析等。
- 建議每批處理人數(shù)<10人,如有大量被試應(yīng)分為多組。一是由于多被試處理時(shí)間長(zhǎng),中間運(yùn)算和調(diào)試周期較長(zhǎng);二是多被試計(jì)算結(jié)果存儲(chǔ)量大,MATLAB對(duì)于2GB以上的數(shù)據(jù)存儲(chǔ)較慢,并且下一階段讀取也緩慢。
- 去暫態(tài)20s,temp_abandon = 20,是由于一般腦電設(shè)備開機(jī)后需要穩(wěn)定波形,這個(gè)數(shù)值要根據(jù)設(shè)備、現(xiàn)場(chǎng)環(huán)境修改。
3.1 數(shù)據(jù)導(dǎo)入
導(dǎo)入原始數(shù)據(jù),并輸出顯示基本數(shù)據(jù)信息:
%% 1.Standard_input % 0.1 rest_data 輸入數(shù)據(jù)格式為:通道數(shù)*采樣點(diǎn)數(shù) standard_time = floor(size(raw_temp_data,2)/fs_raw- temp_abandon); remain_raw_time = standard_time - temp_abandon; remain_trial = floor(remain_raw_time/epoch_length); remain_confrim_time = remain_trial * epoch_length;disp(['數(shù)據(jù)總時(shí)長(zhǎng): ' , num2str(standard_time) , '||暫態(tài)時(shí)長(zhǎng): ' , num2str(temp_abandon), '||修正剩余時(shí)長(zhǎng): ' , num2str(remain_confrim_time)]); disp(['采樣率: ' , num2str(fs_raw), '||每段時(shí)長(zhǎng): ' , num2str(epoch_length), '||試次數(shù)量: ' , num2str(remain_trial)]);3.2 前置準(zhǔn)備-主函數(shù)
主要功能依靠調(diào)用 Standard_cut_rest 函數(shù)實(shí)現(xiàn):
%% 1.切分?jǐn)?shù)據(jù) disp(['數(shù)據(jù)分段中...']); Standard_input_target = []; Standard_input_nontarget = [];Standard_input_target.fs = fs_down; Standard_input_nontarget.fs = fs_down;Standard_input_target.subject_num = subject_num; Standard_input_nontarget.subject_num = subject_num;[Standard_input_target.data,Standard_input_nontarget.data] = Standard_cut_rest(data_path,stuct_name,file_name_target,file_name_nontarget,fs_raw,fs_down,subject_num,remain_trial,epoch_length,temp_abandon,perocess_channel); Standard_input_target.file = file_name_target; Standard_input_nontarget.file = file_name_nontarget; disp(['||已完成標(biāo)準(zhǔn)分段||']);3.3 前置準(zhǔn)備-功能函數(shù)
主功能函數(shù) Standard_cut_rest :
function[Standard_input_target,Standard_input_nontarget] = Standard_cut_rest(data_path,stuct_name,file_name_target,file_name_nontarget,fs_raw,fs_down,subject_num,remain_trial,epoch_length,temp_abandon,perocess_channel) %% 0.參數(shù)說明 % data_path 數(shù)據(jù)路徑 % file_name_target 目標(biāo)數(shù)據(jù)統(tǒng)一名 % file_name_nontarget 非目標(biāo)數(shù)據(jù)統(tǒng)一名 % fs_raw 原始數(shù)據(jù)采樣率 % subject_num 被試起止編號(hào) % remain_trial 剩余試次數(shù) % epoch_length 單試次時(shí)長(zhǎng) % temp_abandon 暫態(tài)去除時(shí)長(zhǎng) % perocess_channel 有效數(shù)據(jù)通道的首末 Standard_input_target = cell(remain_trial,subject_num(2,1)-subject_num(1,1)+1); Standard_input_nontarget = cell(remain_trial,subject_num(2,1)-subject_num(1,1)+1);%% 1.切分?jǐn)?shù)據(jù) print_count=0; sub_count = 1; for sub_loop = subject_num(1,1):subject_num(2,1) raw_data_target = load ([data_path ,file_name_target , num2str(sub_loop)]); raw_data_target = raw_data_target.(stuct_name).data; raw_data_target = downsample(raw_data_target',fs_raw/fs_down)';raw_data_nontarget = load ([data_path ,file_name_nontarget , num2str(sub_loop)]); raw_data_nontarget = raw_data_nontarget.(stuct_name).data; raw_data_nontarget = downsample(raw_data_nontarget',fs_raw/fs_down)';temp_abandon_point = temp_abandon * fs_down; for trial_loop = 1:remain_trialcut_temp = [];cut_temp = raw_data_target(perocess_channel(1,1):perocess_channel(2,1), temp_abandon_point+ (trial_loop-1)*fs_down*epoch_length+1 : temp_abandon_point + trial_loop*fs_down*epoch_length);Standard_input_target{trial_loop,sub_count} = cut_temp;cut_temp = [];cut_temp = raw_data_nontarget(:, temp_abandon_point+ (trial_loop-1)*fs_down*epoch_length+1 : temp_abandon_point + trial_loop*fs_down*epoch_length);Standard_input_nontarget{trial_loop,sub_count} = cut_temp; end % disp(['輸入標(biāo)準(zhǔn)化分段: ' , num2str(sub_loop/subject_num)]);fprintf(repmat('\b',1,print_count)); print_count=fprintf('計(jì)算標(biāo)準(zhǔn)化分段進(jìn)度 : %f',sub_count/(subject_num(2,1) - subject_num(1,1)+1)); sub_count = sub_count+1; end fprintf('\n'); end3.4 前置準(zhǔn)備-結(jié)果保存
最終,結(jié)果保存:
%% 2.保存標(biāo)準(zhǔn)輸入文件 disp(['標(biāo)準(zhǔn)分段保存中...']); save([ svae_path , 'Standard_input_target_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))],'Standard_input_target'); save([ svae_path , 'Standard_input_nontarget_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))],'Standard_input_nontarget'); disp(['||已完成標(biāo)準(zhǔn)分段保存||']); t_Standard_input_cost = toc; disp(['標(biāo)準(zhǔn)輸入格式調(diào)整完畢,耗時(shí): ',num2str(t_Standard_input_cost)]);四、前置準(zhǔn)備 整體代碼
靜息態(tài)信號(hào)整體代碼:
disp(['||0.靜息態(tài)類數(shù)據(jù)處理-標(biāo)準(zhǔn)輸入格式||']); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 0.!!!需手動(dòng)調(diào)整參數(shù) data_path = 'C:\Users\Amax\Desktop\basetest_flod\raw_data_flod\'; svae_path = 'C:\Users\Amax\Desktop\basetest_flod\save_fold\'; file_name_target = 'ADHD'; file_name_nontarget = 'Normal'; stuct_name = 'Data';raw_temp_data = load ([data_path ,file_name_target,'1']); raw_temp_data = raw_temp_data.Data.data; fs_raw = 500; fs_down = 250; %降采樣后采樣率 subject_num = [1;10]; temp_abandon = 20; %去掉的暫態(tài),以秒為單位 epoch_length = 2; perocess_channel = [1 ; 128]; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tic; %% 1.Standard_input % 0.1 rest_data 輸入數(shù)據(jù)格式為:通道數(shù)*采樣點(diǎn)數(shù) standard_time = floor(size(raw_temp_data,2)/fs_raw- temp_abandon); remain_raw_time = standard_time - temp_abandon; remain_trial = floor(remain_raw_time/epoch_length); remain_confrim_time = remain_trial * epoch_length;disp(['數(shù)據(jù)總時(shí)長(zhǎng): ' , num2str(standard_time) , '||暫態(tài)時(shí)長(zhǎng): ' , num2str(temp_abandon), '||修正剩余時(shí)長(zhǎng): ' , num2str(remain_confrim_time)]); disp(['采樣率: ' , num2str(fs_raw), '||每段時(shí)長(zhǎng): ' , num2str(epoch_length), '||試次數(shù)量: ' , num2str(remain_trial)]);%% 1.切分?jǐn)?shù)據(jù) disp(['數(shù)據(jù)分段中...']); Standard_input_target = []; Standard_input_nontarget = [];Standard_input_target.fs = fs_down; Standard_input_nontarget.fs = fs_down;Standard_input_target.subject_num = subject_num; Standard_input_nontarget.subject_num = subject_num;[Standard_input_target.data,Standard_input_nontarget.data] = Standard_cut_rest(data_path,stuct_name,file_name_target,file_name_nontarget,fs_raw,fs_down,subject_num,remain_trial,epoch_length,temp_abandon,perocess_channel); Standard_input_target.file = file_name_target; Standard_input_nontarget.file = file_name_nontarget; disp(['||已完成標(biāo)準(zhǔn)分段||']);%% 2.保存標(biāo)準(zhǔn)輸入文件 disp(['標(biāo)準(zhǔn)分段保存中...']); save([ svae_path , 'Standard_input_target_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))],'Standard_input_target'); save([ svae_path , 'Standard_input_nontarget_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))],'Standard_input_nontarget'); disp(['||已完成標(biāo)準(zhǔn)分段保存||']); t_Standard_input_cost = toc; disp(['標(biāo)準(zhǔn)輸入格式調(diào)整完畢,耗時(shí): ',num2str(t_Standard_input_cost)]);總結(jié)
前置準(zhǔn)備是數(shù)據(jù)處理的敲門磚,本文僅進(jìn)行了基礎(chǔ)的處理。
本文中靜息態(tài)的前置準(zhǔn)備,通過主功能函數(shù) Standard_cut_rest 實(shí)現(xiàn)
靜息態(tài)數(shù)據(jù)無時(shí)間錨點(diǎn)(triger,marker),數(shù)據(jù)分段較為簡(jiǎn)單,一般分為等間距的數(shù)據(jù)段即可
當(dāng)然
實(shí)際應(yīng)用時(shí)會(huì)面臨很多潛在的工程問題,例如儀器數(shù)據(jù)格式、軟件運(yùn)行內(nèi)存、硬件運(yùn)行時(shí)間等等…
代碼工程嘛,就是面對(duì)現(xiàn)實(shí)…
掛一漏萬,如有筆誤請(qǐng)大家指正~
感謝您耐心的觀看,本系列更新了約30000字,約3000行開源代碼,體量相當(dāng)于一篇碩士工作。
往期內(nèi)容放在了文章開頭,麻煩幫忙點(diǎn)點(diǎn)贊,分享給有需要的朋友~
堅(jiān)定初心,本博客永遠(yuǎn):
免費(fèi)拿走,全部開源,全部無償分享~
To:新想法、鬼點(diǎn)子的道友:
自己:腦機(jī)接口+人工智領(lǐng)域,主攻大腦模式解碼、身份認(rèn)證、仿腦模型…
在讀博士第3年,在最后1年,希望將代碼、文檔、經(jīng)驗(yàn)、掉坑的經(jīng)歷分享給大家~
做的不好請(qǐng)大佬們多批評(píng)、多指導(dǎo)~ 虛心向大伙請(qǐng)教!
想一起做些事情 or 奇奇怪怪點(diǎn)子 or 單純批評(píng)我的,請(qǐng)至Rongkaizhang_bci@163.com
總結(jié)
以上是生活随笔為你收集整理的脑电EEG代码开源分享 【1.前置准备-静息态篇】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux vim替换指定字符串
- 下一篇: 51单片机延时与按钮响应时间答复:模拟发