用Matlab完成 PhysioNet MI 数据集裁切、处理与存储(附完整代码)
数据集描述(以运动想象数据为例)
数据集地址:https://physionet.org/content/eegmmidb/1.0.0/
其包含109个用户的运动想象与真实运动数据,每个用户都会执行以下四种任务:
- Task 1 = ”左拳或右拳打开或关闭,真实的运动“
- Task 2 = ”想象左拳或右拳的开合,实际不进行运动“
- Task 3 = ”左脚或右脚打开或关闭,真实的运动“
- Task 4 = ”想象左脚或右脚打开或关闭,实际不进行运动“
每个用户会按照图中顺序,进行不同的Task,共进行14轮次,数据集将轮次称为”run“。每一”run“中(除去1、2的基线”run“),数据包含对应Task的30个样本,采样率为160Hz,通道数为64。
![](https://i-blog.csdnimg.cn/blog_migrate/00fdb9f52eacf6a9ca49158a7299e62e.png)
数据集格式(以运动想象数据为例)
将数据下载完毕后,共109个文件夹,对应109名被试者的数据,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/5ce1e23857f8edb7cf798e3b2547fdfa.png)
每个文件夹中,可以寻找到每一轮次(Run)的”.edf“数据,共14个edf文件与其对应的”.event“文件:
![](https://i-blog.csdnimg.cn/blog_migrate/f3418b08762653b823bc04f445944a34.png)
数据集读取(附完整代码)
这里我利用Matlab读取EEG数据,读取前需要安装EEGLab,这个网上很多教程,大家自行搜索。利用EEGLab的"pop_biosig"函数完成对应“.edf”数据的读取,如若出现报错大家记得在EEGLab中更新这个函数。
读取时只需指定对应的“subject”与“run”就可以,如读取第一个用户第三个run的数据(即读取“S001R03.edf”),代码如下:
subject = 1;
Run = 3;
Physio_data_path = '你存放数据集的路径\';
if subject < 10
if Run < 10
EEG = pop_biosig([Physio_data_path, 'S00', int2str(subject), '\', ...
'S00', int2str(subject), 'R0', int2str(Run), '.edf']); % 将edf文件数据加载至EEGlab
event_path = [Physio_data_path, 'S00', int2str(subject), '\'];
filename = ['S00', int2str(subject), 'R0', int2str(Run), '.edf'];
else
EEG = pop_biosig([Physio_data_path, 'S00', int2str(subject), '\', ...
'S00', int2str(subject), 'R', int2str(Run), '.edf']); % 将edf文件数据加载至EEGlab
event_path = [Physio_data_path, 'S00', int2str(subject), '\'];
filename = ['S00', int2str(subject), 'R', int2str(Run), '.edf'];
end
elseif subject < 100
if Run < 10
EEG = pop_biosig([Physio_data_path, 'S0', int2str(subject), '\', ...
'S0', int2str(subject), 'R0', int2str(Run), '.edf']); % 将edf文件数据加载至EEGlab
event_path = [Physio_data_path, 'S0', int2str(subject), '\'];
filename = ['S0', int2str(subject), 'R0', int2str(Run), '.edf'];
else
EEG = pop_biosig([Physio_data_path, 'S0', int2str(subject), '\', ...
'S0', int2str(subject), 'R', int2str(Run), '.edf']); % 将edf文件数据加载至EEGlab
event_path = [Physio_data_path, 'S0', int2str(subject), '\'];
filename = ['S0', int2str(subject), 'R', int2str(Run), '.edf'];
end
else
if Run < 10
EEG = pop_biosig([Physio_data_path, 'S', int2str(subject), '\', ...
'S', int2str(subject), 'R0', int2str(Run), '.edf']); % 将edf文件数据加载至EEGlab
event_path = [Physio_data_path, 'S', int2str(subject), '\'];
filename = ['S', int2str(subject), 'R', int2str(Run), '.edf'];
else
EEG = pop_biosig([Physio_data_path, 'S', int2str(subject), '\', ...
'S', int2str(subject), 'R', int2str(Run), '.edf']); % 将edf文件数据加载至EEGlab
event_path = [Physio_data_path, 'S', int2str(subject), '\'];
filename = ['S', int2str(subject), 'R', int2str(Run), '.edf'];
end
end
读取完毕后,观察数据集结构:
![](https://i-blog.csdnimg.cn/blog_migrate/949d4d472f4b331d6f8fdd8ed7a1b852.png)
其主要包含以下我们需要的数据:
- data:64通道EEG数据
- event = 包含数据的标签、每个trial的起始与结束时间指示(cue)
接下来,使用Matlab读取对应的“data”,并完成滤波、降采样、裁切与标签的制作:
%% 设置参数
left_cut = 0; % 左裁切大小
right_cut = 349; % 右裁切大小
down_rate = 100; % 设置降采样率
low_f = 5; % 设置下滤波频率
high_f = 40; % 设置滤波截止频率
%%
cnt_data = EEG.data; % CNT数据
% 将数据加载成EEGLab格式
train_EEG = pop_importdata('setname','train', ...
'data', cnt_data, ...
'dataformat', 'array', ...
'srate', 160, ...
'nbchan', 64);
train_EEG = pop_reref(train_EEG, []); % 进行平均参考
train_EEG = pop_eegfilt(train_EEG, 5, 40); % 进行FIR滤波
train_EEG = pop_resample(train_EEG, down_rate); % 进行降采样
event = EEG.event; % 包含label、起始cue
for i = 1:size(event,2)
cue(i,1) = event(i).latency;
cnt_label(i,1) = event(i).edftype;
end
cue = round(cue*(10/16));
% 数据裁切
cnt_train = train_EEG.data; % cnt数据合并
trial = size(cue, 1); % 数据集中的trial数目
count = 0;
for tr = 1:trial
if cnt_label(tr) == 1 || cnt_label(tr) == 2
count = count + 1;
I = cnt_train(:, (cue(tr) - left_cut) : (cue(tr) + right_cut));
cnt_subject(count, :, :) = I; % 用户的cnt数据 格式为:[trial, channel, samplepoints]
end
end
indices = cnt_label ~= 3; % 找出为3的索引
cnt_label = cnt_label(indices); % 删除索引为3的行
最后,完成数据的存储:
save_path = '你设置的保存路径\'
cnt_save_name = ['data_', 'MI']; % cnt数据保存名称
label_save_name = ['label_', 'MI']; % label数据保存名称
eval([cnt_save_name,'=data_subject_MI',';']); % 将字符串转换为matlab可执行语句
eval([label_save_name,'=label_subject_MI',';']); % 将字符串转换为matlab可执行语句
save([save_path,'\data_', 'MI','.mat'],['data_', 'MI']);
save([save_path,'\label_', 'MI','.mat'],['label_', 'MI']);