日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

脑电EEG代码开源分享 【2.预处理-静息态篇】

發布時間:2023/12/10 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 脑电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;,定義為壞導
    %% 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)]);

    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或降低低通參數']); end

    3.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 endend

    3.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 endend

    3.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 endend

    3.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;end

    3.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 endend

    3.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.预处理-静息态篇】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。