基于肌电信号(sEMG) 的深度学习手势分类

在过去的几年里,科研界对使用基于表面肌电信号 (sEMG) 的深度学习方法进行手势分类产生了浓厚的兴趣。根据该领域的最新工作,我的工作目标是设计一种新颖的卷积神经网络架构,用于手势分类。我的模型虽然避免了过度拟合,但与更浅的网络相比,性能并没有显着提高。结果表明,某些手势之间的 sEMG 记录缺乏多样性,从而限制了 ML 模型的性能。

然而,我使用商业设备 (Myo Armband) 开发的数据集的分类准确度明显高于使用相同设备记录的类似基准数据集(约 24%)。

MyoUP 数据集

为了有助于获取 sEMG 数据,特别是从不需要专业校准的设备中获取,我开发了一个相当大的 sEMG 数据集。我们的数据集 MyoUP 受到 Ninapro 数据集的启发,所有记录的手势都与 Ninapro 中的一些 ( http://ninaweb.hevs.ch ) 相同。我们使用的录音设备是 Thalmic 实验室的 Myo Armband。Myo Armband 是一种相对便宜且易于佩戴的设备,其采样频率为 200Hz,8 个干式 sEMG 通道已在科学研究中广泛采用。

MyoUP 数据集包含来自 8 名完整受试者的记录(3 名女性,5 名男性;1 名左撇子,7 名右手;年龄 22.38 ± 1.06 岁)。采集过程分为三个部分:5 个基本手指动作、12 个等张和等长手部配置以及 5 个抓握手势。在进行每组练习之前,志愿者已经习惯了该程序。指示受试者重复每个手势 5 次,持续 5 秒,中间有 5 秒的中断,以避免肌肉疲劳。一名主管协助受试者将 Myo Armband 戴在他们的惯用手上,以便将设备放置在受试者舒适的位置,并且设备将准确检测 sEMG 信号。受试者可以在屏幕上看到 sEMG 以及必须执行的手势图片。

实时手势识别
通过使用来自 MyoUP 数据集的 sEMG 记录训练我们的 CNN,我设法开发了一个实时手势识别软件。

在这里插入图片描述
在这里插入图片描述
数据处理的matlab文件

%% Training signals - creation - Myo - step #1
clc;
clear all;

START = 's';
END = 'e1.mat';
filename = "s";

for subject = 1 : 8
    %_________________________________________
    code = strcat(START,int2str(subject),END);
    disp(code);

    struct = load(code);
    rep = struct.pulse;
    emg = struct.emg;
   %_________________________________________

    counter = 1;
    points = zeros(1, 50);
    
    for i = 2 : length(rep)
        if(rep(i - 1) == 0 && rep(i) > 0)
            points(counter) = i;
            counter = counter + 1;
        end
        if(rep(i - 1) > 0 && rep(i) == 0)
            points(counter) = i - 1;
            counter = counter + 1;
        end 
    end
    
   
    counter = 1;
    repeat = 0;
    exercise = 0;
    exe_number = 1;
    
    for i = 1 : length(points) / 2
        starting_point = points(counter);
        counter = counter + 1;
        finishing_point = points(counter);
        counter = counter + 1;
        
         disp(starting_point)
         disp(finishing_point)
         disp('______________')
        
        repeat = repeat + 1;
        exercise = exercise + 1;
        
        columns = finishing_point - starting_point + 1;
        matrix = zeros(8, columns);
         
        column = 1;
        for pointer = starting_point : finishing_point
            for channel = 1 : 8
                matrix(channel, column) = emg(pointer, channel);
            end
            column = column + 1;
        end
         
        file = filename + subject + "e" + exe_number + "rep" + repeat + ".mat";
        save(file, 'matrix')
        
        if(repeat == 5)
            repeat = 0;
        end
        if(exercise == 5)
            exercise = 0;
            exe_number = exe_number + 1;
        end
    end
end   


%% Maximum Size Matrix - step #2

clc;

maximum_size = 0;

emg_sizes = zeros(1, 3400);
counter = 0;

for subject = 1 : 8
    for exercise = 1 : 5
        for repetition = 1 : 5
            
            counter = counter + 1;
             
            filename = strcat('s', int2str(subject), 'e', int2str(exercise), 'rep', int2str(repetition));
            path = 'Myo_training\E1\';
            
            load_path = strcat(path, filename);
            load_path = strcat(load_path, '.mat');
            
            signal = load(load_path); 
            matrix = signal.matrix;
            
            matrix_size = size(matrix); matrix_size = matrix_size(2);
            emg_sizes(1, counter) = matrix_size;
            
            if(matrix_size > maximum_size)
                maximum_size = matrix_size;
            end
        end
    end
end

%% Training Images - creation II - step #3

clear all;
clc;

for subject = 1 : 8
    disp('Subject: ');
    disp(subject)
    for exercise = 1 : 12
        for repetition = 1 : 5
            
            filename = strcat('s', int2str(subject), 'e', int2str(exercise), 'rep', int2str(repetition));
            path = 'Myo_training\E2\';
            
            load_path = strcat(path, filename);
            load_path = strcat(load_path, '.mat');
            
            signal = load(load_path); 
            
            original_matrix = signal.matrix;
            noisy_matrix = awgn(original_matrix,25);
            
            matrix_size = size(original_matrix); matrix_size = matrix_size(2);
            window_type_one = matrix_size / 6;
            window_type_one = int16(fix(window_type_one));
            window_type_two = 226 - window_type_one;
            
            if(window_type_one > 226)
                window_type_one = 225;
            end
            
            start_index = 1;
            end_index = 15;

%________%: Normal Windows.    
            
            for div = 1 : window_type_one
                if(exercise ~= 10 && exercise ~= 11 && exercise ~= 12)
                    filename = strcat('X2_e0', int2str(exercise), '_s', int2str(subject), '_E2_rep', int2str(repetition));
                    fn = strcat('X2_e0', int2str(exercise), '_s', int2str(subject), '_E2_rep', int2str(repetition));
                else
                    filename = strcat( 'X2_e', int2str(exercise), '_s', int2str(subject), '_E2_rep', int2str(repetition));
                    fn = strcat( 'X2_e', int2str(exercise), '_s', int2str(subject), '_E2_rep', int2str(repetition));
                end

                counter = 1;
                
                if(end_index <= matrix_size) 
                    filename = strcat(filename, '_image', int2str(div));

                    if(repetition == 1 || repetition == 3 || repetition == 5)
                        save_matrix_path = strcat('EMG_data\train_set\' , filename, '.mat');
                        save_matrix_path_gaussian = strcat('EMG_data\train_set\' , filename, '_GAUSSIAN.mat'); 
                    end

                    if(repetition == 2)
                        save_matrix_path = strcat('EMG_data\test_set\' , filename, '.mat');
                        save_matrix_path_gaussian = strcat('EMG_data\test_set\' , filename, '_GAUSSIAN.mat');
                    end

                    if(repetition == 4)
                        save_matrix_path = strcat('EMG_data\val_set\' , filename, '.mat');
                        save_matrix_path_gaussian = strcat('EMG_data\val_set\' , filename, '_GAUSSIAN.mat'); 
                    end

                    image = zeros(8, 15);
                    image = original_matrix(1:8, start_index : end_index);
                    
                    save(save_matrix_path, 'image')
                    
                    image = zeros(8, 15);
                    image = noisy_matrix(1:8, start_index : end_index);

                    save(save_matrix_path_gaussian, 'image')
                    
                    start_index = start_index + 6;
                    end_index = end_index + 6;
                else
                    div = div - 1;
                end
            end

%________%: Random Windows.

            for index = div : 226
                
                limit = matrix_size - 20;
                random_number = randi([1,limit]);
                
                index_start_random = random_number;
                index_end_random = index_start_random + 14;

                if(repetition == 1 || repetition == 3 || repetition == 5)
                    save_path = strcat('EMG_data\train_set\' , fn, '_image', int2str(index), '.mat');
                    save_path_gaussian = strcat('EMG_data\train_set\' , fn, '_image', int2str(index), '_GAUSSIAN.mat');
                end
                
                if(repetition == 2)
                    save_path = strcat('EMG_data\test_set\' , fn, '_image', int2str(index), '.mat');
                    save_path_gaussian = strcat('EMG_data\test_set\' , fn, '_image', int2str(index), '_GAUSSIAN.mat');
                end
                
                if(repetition == 4)
                    save_path = strcat('EMG_data\val_set\' , fn, '_image', int2str(index), '.mat');
                    save_path_gaussian = strcat('EMG_data\val_set\' , fn, '_image', int2str(index), '_GAUSSIAN.mat');
                end
                   
                image = zeros(8, 15); 
                
                image = original_matrix(1:8, index_start_random : index_end_random);
                save(save_path, 'image');
                
                image = zeros(8, 15);
                
                image = noisy_matrix(1:8, index_start_random : index_end_random);
                save(save_path_gaussian, 'image')
                
            end
        end
    end
end
  • 5
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr Robot

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值