脑电EEG代码开源分享 【2.预处理-静息态篇】
往期文章
希望了解更多的道友點這里
0. 分享【腦機接口 + 人工智能】的學習之路
1.1 . 腦電EEG代碼開源分享 【1.前置準備-靜息態篇】
1.2 . 腦電EEG代碼開源分享 【1.前置準備-任務態篇】
2.1 . 腦電EEG代碼開源分享 【2.預處理-靜息態篇】
2.2 . 腦電EEG代碼開源分享 【2.預處理-任務態篇】
3.1 . 腦電EEG代碼開源分享 【3.可視化分析-靜息態篇】
3.2 . 腦電EEG代碼開源分享 【3.可視化分析-任務態篇】
4.1 . 腦電EEG代碼開源分享 【4.特征提取-時域篇】
4.2 . 腦電EEG代碼開源分享 【4.特征提取-頻域篇】
4.3 . 腦電EEG代碼開源分享 【4.特征提取-時頻域篇】
4.4 . 腦電EEG代碼開源分享 【4.特征提取-空域篇】
5 . 腦電EEG代碼開源分享 【5.特征選擇】
6.1 . 腦電EEG代碼開源分享 【6.分類模型-機器學習篇】
6.2 . 腦電EEG代碼開源分享 【6.分類模型-深度學習篇】
匯總. 專欄:腦電EEG代碼開源分享【文檔+代碼+經驗】
0 . 【深度學習】常用網絡總結
腦電EEG代碼開源分享 【2.預處理-靜息態篇】
- 往期文章
- 一、前言
- 二、預處理 框架介紹
- 三、代碼格式說明
- 三、腦電處理 代碼
- 3.0 參數設置
- 3.1 標準輸入賦值
- 3.2 預處理
- 3.2.1 預處理-基線矯正
- 3.2.2 預處理-濾波
- 3.2.3 預處理-剔除壞導
- 3.2.4 預處理-自動填補、修復壞導
- 3.2.5 預處理-剔除壞樣本試次
- 3.3 預處理-結果保存
- 四、預處理 整體代碼
- 總結
- To:新想法、鬼點子的道友:
一、前言
本文檔旨在歸納BCI-EEG-matlab的數據處理代碼,作為EEG數據處理的總結,方便快速搭建處理框架的Baseline,實現自動化、模塊插拔化、快速化。本文以任務態(鎖時刺激,如快速序列視覺呈現)為例,分享腦電EEG的分析處理方法。
腦電數據分析系列。分為以下6個模塊:
本文內容:【2. 數據預處理】
提示:以下為各功能代碼詳細介紹,若節約閱讀時間,請下滑至文末的整合代碼
二、預處理 框架介紹
預處理
預處理的主要功能,分為以下5部分:
1. 基線校正
2. 濾波
3. 剔除壞導聯
4. 填充壞導聯
5. 剔除試次
預處理的代碼框圖、流程如下所示:
預處理與前置準備差異在于,預處理對腦電數據進行變換(線型or非線性),改變了原始數據形態
預處理的目的為:提升數據質量、降噪;前置準備的處理目的是:統一格式、保留關鍵數據;
對于預處理內容大致如下,順序依據個人習慣有差異,本人處理順序如下:
-1. 基線校正–2. 濾波–3. 去除壞導聯–4. 填充壞導聯–5. 剔除試次
-
基線校正:去除信號零飄,尤其是信號采集環境不好 or 被試狀態不佳(犯困)。其操作內容為,靜息態(非鎖時任務)減去數據段內均值,根據傅里葉FFT變換推導,其功能相當于數據在0Hz降低了直流信號能量,等于變相的進行了一次直流濾波。由于靜息態等長時間任務沒有刺激誘發錨點,沒有任務態刺激triger的標記,因此一般以本段數據為基線參考。
-
濾波:盡量保留腦電數據“有價值”內容,盡量去除噪聲等偽跡干擾。由于腦電信號幅度為10^-6v,微伏級別的數據能被任何妖魔鬼怪干擾,啥噪聲都能來折磨你(說到動情處,覺得有必要寫一篇腦電EEG采集的苦痛經驗)…濾波不僅需要濾除高頻的干擾,一般過濾掉靜息態信號中100Hz以上無關腦活動信息(還沒驗證大腦能產生這么高頻率);還要過濾掉0.5Hz Or 1Hz 以下的低頻偽跡,一般認為這是肌電、電極與頭皮摩擦、心電(一秒鐘跳一下多)產生的。其操作內容為,帶通濾波0.05Hz-80Hz(也有0.01-100Hz等多種組合),可以使用高通0.05Hz + 低通80Hz,也可以使用0.05Hz-80Hz的帶通。注:濾波器不是直上直下的,設計時應考慮 過渡帶 + 帶內抖動,,尤其是高通0.5Hz的過渡帶區間窄,尤其難設計濾波器參數,詳細知識可學習參考《數字信號處理》。我們這里經驗設置的:低通Rp_low = 0.5;Rs_low =5 ; 高通Rp_high =1;Rs_high =10。
-
剔除壞導聯(電極):由于實驗過程中的環境噪聲、電極不貼合、電極線故障等原因,導致單個或多個電極質量不佳,若不對個別壞道進行剔除、修復,下一步會影響整體數據質量。量化各電極通道的信號質量,對信號質量嚴重受損的通道進行標記、置零,為下一階段導聯修復、填充做準備。導聯質量觀測可分為兩種,一是在數據采集過程中就發現,肉眼可見的信號質量不佳,此類壞導易標記;另一種是數據處理過程中發現的壞導,大家量化方法不一。我們提出的應用導聯方差的量化方法,當某導聯方差大于平均方差幾倍時,則認為該導聯抖動異常 應剔除,這里倍數的經驗值為3,outlier_threshold=3,這個閾值是根據數據實際修改的,最終目的是保留80%以上的樣本,如果信號整體質量偏高就降低閾值(例如到2),如果信號整體質量偏低就提升閾值(例如到5).
-
填充壞導聯(電極):壞導在上一階段進行了標記,但若壞導個數偏多 or 導聯密度有要求,則需要對原壞導位置進行修復 or 填充。常用的方法是用相鄰導聯的數據進行均值替換,可用壞導附近的2導、4導、8導的均值代替壞導數據。
-
剔除試次:被試在進行某次任務 or 實驗某階段的樣本質量不佳。目前研究普遍認為靜息態腦電信號不高于100uv(有爭論但在100uv上下浮動),因此一般認為幅值超過100uv的樣本質量不佳,一般處理方法就是直接刪除該樣本。但是100uv也并非固定的,也會因為信號質量浮動,論文中的閾值80uv 、100uv、120uv、150uv我都見過,大家還是秉承工程思想,在滿足最低樣本量的基礎上,最大程度保證樣本質量。
-
重參考:重參考是尋找大腦的電位0點,相減電位零點以使全腦電極有統一基準。重參考電勢零點的尋找有多個研究室團隊探討,例如平均參考、雙側乳突參考、REST參考等。由于這一步驟在硬件采集時設置了雙耳乳突參考,因此本代碼中未進行該操作。
(有需要的朋友可以留言,還有哪些參數設置比較困惑,可以再寫一篇談談數據處理、實驗設計中的參數設置)
三、代碼格式說明
本文非鎖時任務態(下文以靜息態代替)范例為:ADHD患者、正常人群在靜息狀態下的腦模式分類
- **代碼名稱:**代碼命名為Proprocess_xxx ( baseline \ filter \ channel_abandon\ trial_abandon)
- **輸入格式:**輸入格式承接規范輸入的文件Standard_input_xx。
- **輸出及保存格式:**分預處理階段階保存數據,數據仍為分類別保存,保存命名為Proprocess_xxx(預處理名稱)_target/nontarget。除abandon階段外其余預處理過程的cell格式同規范輸入數據,abandon階段數據仍為cell{1,通道數},只改變通道數內的剩余試次數[剩余試次數,512]。
三、腦電處理 代碼
提示:代碼環境為 matlab 2018
3.0 參數設置
預處理內容可以選擇,把希望進行的步驟寫在proprocess_content 中
- 預處理內容: proprocess_content = [‘baseline’,‘filter’,‘channel_abandon’,‘auto_abandon’,‘trial_abandon’]; 1. 基線校正 2. 濾波 3. 剔除壞導聯 4. 填充壞導聯 5. 剔除試次.
- 剔除壞導:試驗中肉眼發現16導信號不佳,channel_abandon_num = [16];
- 剔除超過100uv的樣本試次,trial_threshold = 100;
- 一次進行10人次的批處理,subject_num = [1;29]
- 取數據段內20%長度的數據均值進行基線矯正,Baseline_reference = [0;0.2];
- 帶通濾波范圍:0.01Hz-100Hz,低通起止頻率為80Hz、100Hz,高通起止頻率為0.01Hz、1Hz,filter_low_para = [80;100]; filter_high_para = [0.01;1];
- 壞導量化倍率3,當某導聯方差為平均值的3倍以上,outlier_threshold = 3;,定義為壞導
3.1 標準輸入賦值
導入前置準備階段處理后的數據:
%% 1.標準輸入賦值 disp(['||1.靜息態or任務態-標準輸入數據加載中...||']); Standard_nontarget_file = load([data_path , 'Standard_input_nontarget_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))]); Standard_target_file = load([data_path , 'Standard_input_target_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))]); stuct_target_name = 'Standard_input_target'; stuct_nontarget_name = 'Standard_input_nontarget';Standard_nontarget_data = Standard_nontarget_file.(stuct_nontarget_name).data; Standard_target_data = Standard_target_file.(stuct_target_name).data;subject_num = Standard_target_file.(stuct_target_name).subject_num; fs_down = Standard_target_file.(stuct_target_name).fs; trial_every_sub = size(Standard_target_data,1); disp(['被試量: ' , num2str(subject_num(1,1)),'-',num2str(subject_num(2,1))]);if (filter_low_para(2,1)>fs_down/2) disp(['低通濾波參數不符合奈奎斯特帶寬,請調高fs_down或降低低通參數']); end3.2 預處理
3.2.1 預處理-基線矯正
主體調用函數Proprocess_baseline
%2.1 基線矯正 if contains(proprocess_content,'baseline') Proprocess_baseline_target = Proprocess_baseline(Standard_target_data,fs_down,Baseline_reference); Proprocess_baseline_nontarget = Proprocess_baseline(Standard_nontarget_data,fs_down,Baseline_reference); end主功能函數 Proprocess_baseline:
function baseline_out= Proprocess_baseline(Standard_input_data,fs_down,Baseline_reference) % Standard_input_data 標準輸入的cell腦電數據,cell(試次數*被試數)[通道數,時間點數] % fs_down 標準輸入時降采樣率 % Baseline_reference 極限矯正的參考時間段,一般為0~0.2的試次前均值,或者0~1的全時段均值baseline_start = floor(Baseline_reference(1,1)*fs_down)+1; baseline_end = floor(Baseline_reference(2,1)*fs_down);baseline_out = cell(size(Standard_input_data,1),size(Standard_input_data,2));for trial_loop = 1:size(Standard_input_data,1) for sub_loop = 1:size(Standard_input_data,2) for channel_loop = 1:size(Standard_input_data{1,1},1)if ~isempty(Standard_input_data{trial_loop,sub_loop})baseline_out{trial_loop,sub_loop}(channel_loop,:) = Standard_input_data{trial_loop,sub_loop}(channel_loop,:) - mean(Standard_input_data{trial_loop,sub_loop}(channel_loop,baseline_start:baseline_end)); end end end endend3.2.2 預處理-濾波
主體調用函數Proprocess_filter
%2.2 濾波 if contains(proprocess_content,'filter') Proprocess_filter_target = Proprocess_filter(Proprocess_baseline_target,fs_down,filter_low_para,filter_high_para); Proprocess_filter_nontarget = Proprocess_filter(Proprocess_baseline_nontarget,fs_down,filter_low_para,filter_high_para); end主功能函數 Proprocess_filter:
function [filter_out]= Proprocess_filter(Standard_input_data,fs_down,filter_low_para,filter_high_para)%導入參數 low_start = filter_low_para(1,1); low_end = filter_low_para(2,1); high_start =filter_high_para(1,1); high_end = filter_high_para(2,1); filter_out = cell(size(Standard_input_data,1),size(Standard_input_data,2)); % 低通 Rp_low = 0.5; Rs_low =5; [N_low,Wpo_low]=cheb1ord(2*low_start/fs_down,2*low_end/fs_down,Rp_low,Rs_low); [b_low,a_low]=cheby1(N_low,Rp_low,Wpo_low,'low');% 高通 Rp_high =1; Rs_high =10; [N_high,Wpo_high]=cheb1ord(2*high_end/fs_down,2*high_start/fs_down,Rp_high,Rs_high); [b_high,a_high]=cheby1(N_high,Rp_high,Wpo_high,'high');% 濾波 for trial_loop = 1:size(Standard_input_data,1) for sub_loop = 1:size(Standard_input_data,2) for channel_loop = 1:size(Standard_input_data{1,1},1) if ~isempty(Standard_input_data{trial_loop,sub_loop})temp_filter = [];temp_filter = filter(b_low,a_low,Standard_input_data{trial_loop,sub_loop}(channel_loop,:));temp_filter = filter(b_high,a_high,temp_filter); filter_out{trial_loop,sub_loop}(channel_loop,:) = temp_filter; end end end endend3.2.3 預處理-剔除壞導
主體調用函數Proprocess_channel_abandon
%2.3 多余通道剔除 if contains(proprocess_content,'channel_abandon') Proprocess_channel_abandon_target = Proprocess_channel_abandon(Proprocess_filter_target,channel_abandon_num); Proprocess_channel_abandon_nontarget = Proprocess_channel_abandon(Proprocess_filter_nontarget,channel_abandon_num); end主功能函數 Proprocess_channel_abandon:
function channel_abandon_out= Proprocess_channel_abandon(Standard_input_data,channel_abandon_num) % Standard_input_data 標準輸入的cell腦電數據,cell(試次數*被試數)[通道數,時間點數] % channel_abandon_num 舍棄通道編號 abandon_size = size(channel_abandon_num,1);channel_abandon_out = cell(size(Standard_input_data,1),size(Standard_input_data,2));for sub_loop = 1:size(Standard_input_data,2) for trial_loop = 1:size(Standard_input_data,1)channel_count = 1; for channel_loop = 1:size(Standard_input_data{1,1},1) if ~isempty(Standard_input_data{trial_loop,sub_loop}) if isempty(find(channel_abandon_num==channel_loop))channel_abandon_out{trial_loop,sub_loop}(channel_count,:) = Standard_input_data{trial_loop,sub_loop}(channel_loop,:); channel_count = channel_count+1; end end end end endend3.2.4 預處理-自動填補、修復壞導
主體調用函數Proprocess_auto_abandon
%2.4 異常通道自動替換 if contains(proprocess_content,'auto_abandon') [Proprocess_auto_abandon_target,auto_channel_list_target] = Proprocess_auto_abandon(Proprocess_channel_abandon_target,outlier_threshold); [Proprocess_auto_abandon_nontarget,auto_channel_list_nontarget] = Proprocess_auto_abandon(Proprocess_channel_abandon_nontarget,outlier_threshold); end主功能函數 Proprocess_auto_abandon:
function [auto_abandon_data,auto_channel_list]= Proprocess_auto_abandon(Standard_input_data,outlier_threshold) %% 注:auto_abandon只是將抖動異常通道使用相鄰通道替換,而不影響數據通道個數,處理后數據通道個數仍一致% Standard_input_data 標準輸入的cell腦電數據,cell(試次數*被試數)[通道數,時間點數] % outlier_threshold 為異常點的閾值,即異常點抖動是均值的幾倍則被判為異常點,一般設為5 % auto_abandon_data 為自動修正(用周圍通道替換)通道后的數據 % auto_channel_list 為各被試替換的通道列表channel_temp_std = []; auto_channel_list = cell(1,size(Standard_input_data,2)); for sub_loop = 1:size(Standard_input_data,2)abandon_count = 1;channel_temp_std = [];for trial_loop = 1:size(Standard_input_data,1)channel_temp_std(:,trial_loop) = std(Standard_input_data{trial_loop,sub_loop}')';end std_mean = mean(channel_temp_std');abandon_level = mean(outlier_threshold*std_mean);for channel_loop = 1:size(Standard_input_data{1,1},1)if std_mean(1,channel_loop) > abandon_levelauto_channel_list{1,sub_loop}(1,abandon_count) = channel_loop;endend endfor sub_loop = 1:size(Standard_input_data,2)if ~isempty(auto_channel_list{1,sub_loop})for trial_loop = 1:size(Standard_input_data,1)for channel_loop = 1:size(Standard_input_data{1,1},1)if ismember( auto_channel_list{1,sub_loop}(1,abandon_count),channel_loop)replace_data=[];if channel_loop==1replace_data = Standard_input_data{trial_loop,sub_loop}(2,:);elseif channel_loop==size(Standard_input_data{1,1},1)replace_data = Standard_input_data{trial_loop,sub_loop}(size(Standard_input_data{1,1},1)-1,:);elsereplace_data = (Standard_input_data{trial_loop,sub_loop}(channel_loop-1,:) + Standard_input_data{trial_loop,sub_loop}(channel_loop+1,:))/2; endStandard_input_data{trial_loop,sub_loop}(channel_loop,:) = replace_data;endendendend endauto_abandon_data = Standard_input_data;end3.2.5 預處理-剔除壞樣本試次
主體調用函數Proprocess_trial_abandon
%2.5 試次剔除 if contains(proprocess_content,'trial_abandon') Proprocess_trial_abandon_target = Proprocess_trial_abandon(Proprocess_auto_abandon_target,trial_threshold); Proprocess_trial_abandon_nontarget = Proprocess_trial_abandon(Proprocess_auto_abandon_nontarget,trial_threshold); end主功能函數 Proprocess_trial_abandon:
function trial_abandon_out= Proprocess_trial_abandon(Standard_input_data,trial_threshold) % Standard_input_data 標準輸入的cell腦電數據,cell(試次數*被試數)[通道數,時間點數] % trial_abandon_num 舍棄通道編號trial_abandon_out = cell(size(Standard_input_data,1),size(Standard_input_data,2));for sub_loop = 1:size(Standard_input_data,2)trial_count = 1; for trial_loop = 1:size(Standard_input_data,1) if max(max(Standard_input_data{trial_loop,sub_loop}))<trial_thresholdtrial_abandon_out{trial_count,sub_loop}= Standard_input_data{trial_loop,sub_loop}; trial_count = trial_count+1; end end endend3.3 預處理-結果保存
最終,結果保存:
%% 3.預處理數據保存 Proprocess_target = []; Proprocess_target.remain_trial = remain_target_trial; Proprocess_target.fs_down = fs_down; Proprocess_target.subject_num = subject_num; Proprocess_target.data = Proprocess_trial_abandon_target; Proprocess_target.Baseline_reference = Baseline_reference;Proprocess_nontarget = []; Proprocess_nontarget.remain_trial = remain_nontarget_trial; Proprocess_nontarget.fs_down = fs_down; Proprocess_nontarget.subject_num = subject_num; Proprocess_nontarget.data = Proprocess_trial_abandon_nontarget; Proprocess_nontarget.Baseline_reference = Baseline_reference; disp(['標準分段保存中...']); save([ svae_path , 'Proprocess_target_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))],'Proprocess_target'); save([ svae_path , 'Proprocess_nontarget_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))],'Proprocess_nontarget'); disp(['||已完成標準分段保存||']);四、預處理 整體代碼
靜息態信號-預處理 整體代碼:
%% 0.標準數據參數設置 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% data_path = 'C:\Users\Amax\Desktop\basetest_flod\save_fold\'; svae_path = 'C:\Users\Amax\Desktop\basetest_flod\save_fold\';proprocess_content = ['baseline\','filter\','channel_abandon\','auto_abandon\','trial_abandon']; channel_abandon_num = [16];trial_threshold = 100; subject_num = [1 ; 10]; Baseline_reference = [0;0.2]; filter_low_para = [80;100]; filter_high_para = [0.01;1];outlier_threshold = 3;disp(['||預處理參數設置||']); disp(['預處理內容: ' , proprocess_content]); disp(['基線長度: ' , num2str(Baseline_reference(1,1)),'-',num2str(Baseline_reference(2,1))]); disp(['低通起止: ' , num2str(filter_low_para(1,1)),'-',num2str(filter_low_para(2,1))]); disp(['高通起止: ' , num2str(filter_high_para(1,1)),'-',num2str(filter_high_para(2,1))]); disp(['通道舍棄: ' , num2str(channel_abandon_num')]); disp(['試次幅度閾值: ' , num2str(trial_threshold)]);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 1.標準輸入賦值 disp(['||1.靜息態or任務態-標準輸入數據加載中...||']); Standard_nontarget_file = load([data_path , 'Standard_input_nontarget_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))]); Standard_target_file = load([data_path , 'Standard_input_target_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))]); stuct_target_name = 'Standard_input_target'; stuct_nontarget_name = 'Standard_input_nontarget';Standard_nontarget_data = Standard_nontarget_file.(stuct_nontarget_name).data; Standard_target_data = Standard_target_file.(stuct_target_name).data;subject_num = Standard_target_file.(stuct_target_name).subject_num; fs_down = Standard_target_file.(stuct_target_name).fs; trial_every_sub = size(Standard_target_data,1); disp(['被試量: ' , num2str(subject_num(1,1)),'-',num2str(subject_num(2,1))]);if (filter_low_para(2,1)>fs_down/2) disp(['低通濾波參數不符合奈奎斯特帶寬,請調高fs_down或降低低通參數']); end %% 2.預處理 %2.1 基線矯正 if contains(proprocess_content,'baseline') Proprocess_baseline_target = Proprocess_baseline(Standard_target_data,fs_down,Baseline_reference); Proprocess_baseline_nontarget = Proprocess_baseline(Standard_nontarget_data,fs_down,Baseline_reference); end %2.2 濾波 if contains(proprocess_content,'filter') Proprocess_filter_target = Proprocess_filter(Proprocess_baseline_target,fs_down,filter_low_para,filter_high_para); Proprocess_filter_nontarget = Proprocess_filter(Proprocess_baseline_nontarget,fs_down,filter_low_para,filter_high_para); end %2.3 多余通道剔除 if contains(proprocess_content,'channel_abandon') Proprocess_channel_abandon_target = Proprocess_channel_abandon(Proprocess_filter_target,channel_abandon_num); Proprocess_channel_abandon_nontarget = Proprocess_channel_abandon(Proprocess_filter_nontarget,channel_abandon_num); end %2.4 異常通道自動替換 if contains(proprocess_content,'auto_abandon') [Proprocess_auto_abandon_target,auto_channel_list_target] = Proprocess_auto_abandon(Proprocess_channel_abandon_target,outlier_threshold); [Proprocess_auto_abandon_nontarget,auto_channel_list_nontarget] = Proprocess_auto_abandon(Proprocess_channel_abandon_nontarget,outlier_threshold); end %2.5 試次剔除 if contains(proprocess_content,'trial_abandon') Proprocess_trial_abandon_target = Proprocess_trial_abandon(Proprocess_auto_abandon_target,trial_threshold); Proprocess_trial_abandon_nontarget = Proprocess_trial_abandon(Proprocess_auto_abandon_nontarget,trial_threshold); end[remain_target_trial,remain_nontarget_trial]= Proprocess_trial_remain(Proprocess_trial_abandon_target,Proprocess_trial_abandon_nontarget); disp(['目標試次剩余比例: ' , num2str(remain_target_trial/size(Proprocess_trial_abandon_target,1)),'||平均: ', num2str(mean(remain_target_trial/size(Proprocess_trial_abandon_target,1)))]); disp(['非目標試次剩余比例: ' , num2str(remain_nontarget_trial/size(Proprocess_trial_abandon_nontarget,1)),'||平均: ', num2str(mean(remain_nontarget_trial/size(Proprocess_trial_abandon_nontarget,1)))]);%% 3.預處理數據保存 Proprocess_target = []; Proprocess_target.remain_trial = remain_target_trial; Proprocess_target.fs_down = fs_down; Proprocess_target.subject_num = subject_num; Proprocess_target.data = Proprocess_trial_abandon_target; Proprocess_target.Baseline_reference = Baseline_reference;Proprocess_nontarget = []; Proprocess_nontarget.remain_trial = remain_nontarget_trial; Proprocess_nontarget.fs_down = fs_down; Proprocess_nontarget.subject_num = subject_num; Proprocess_nontarget.data = Proprocess_trial_abandon_nontarget; Proprocess_nontarget.Baseline_reference = Baseline_reference; disp(['標準分段保存中...']); save([ svae_path , 'Proprocess_target_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))],'Proprocess_target'); save([ svae_path , 'Proprocess_nontarget_',num2str(subject_num(1,1)),'_',num2str(subject_num(2,1))],'Proprocess_nontarget'); disp(['||已完成標準分段保存||']);總結
預處理最終目的是:提升采集信號質量(前提是還有數據)
但是 數據質量 和 樣本數量,大多數情況下是沖突的
有個前提是保證底線數量的樣本量,如果因為嚴苛的預處理指標,而預處理后不剩幾個樣本,則本末倒置,后續處理無法進行
有時就因為樓下施工,被試困倦,電磁信號,電壓不穩,導致數據質量基礎不好,這都是很正常的
如果再一味地追求高質量的預處理結果,那真的強人所難了…
希望大家在這一階段運用工程思想,以結果導向,在保證樣本多多的情況下,盡量改善數據好好的
記住:一切預處理參數都是活的,必要時可以妥協的
囿于能力,掛一漏萬,如有筆誤請大家指正~
感謝您耐心的觀看,本系列更新了約30000字,約3000行開源代碼,體量相當于一篇碩士工作。
往期內容放在了文章開頭,麻煩幫忙點點贊,分享給有需要的朋友~
堅定初心,本博客永遠:
免費拿走,全部開源,全部無償分享~
To:新想法、鬼點子的道友:
自己:腦機接口+人工智領域,主攻大腦模式解碼、身份認證、仿腦模型…
在讀博士第3年,在最后1年,希望將代碼、文檔、經驗、掉坑的經歷分享給大家~
做的不好請大佬們多批評、多指導~ 虛心向大伙請教!
想一起做些事情 or 奇奇怪怪點子 or 單純批評我的,請至Rongkaizhang_bci@163.com
總結
以上是生活随笔為你收集整理的脑电EEG代码开源分享 【2.预处理-静息态篇】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络资产管理系统_固定资产管理系统的常用
- 下一篇: JavaScript DOM操作 提高篇