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

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

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

以下是Python训练代码

import tensorflow as tf

import numpy as np
import math
import os

from PIL import Image
import time

from sklearn.utils import shuffle
from sklearn.metrics import confusion_matrix

from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import InputLayer, Input, Dropout
from tensorflow.python.keras.layers import Reshape, AveragePooling2D, MaxPooling2D
from tensorflow.python.keras.layers import Conv2D, Dense, Flatten, Activation

from tensorflow.python.keras.optimizers import SGD
from tensorflow.python.keras.optimizers import Adam
from tensorflow.python.keras.optimizers import RMSprop
from tensorflow.python.keras.optimizers import Adadelta

from keras.utils import np_utils

from tensorflow.python.keras.callbacks import TensorBoard
from tensorflow.python.keras.callbacks import EarlyStopping
from tensorflow.python.keras.layers import BatchNormalization
from keras.models import load_model

from sklearn.model_selection import train_test_split

from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV

import itertools
import matplotlib.pyplot as plt
 
import scipy.io as sio

NAME = "Train_Myo_Tsagkas_v2_{}".format(int(time.time()))
tensorboard = TensorBoard(log_dir = 'logs/{}'.format(NAME))

def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    else:
        print('Confusion matrix, without normalization')

    print(cm)

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.tight_layout()
    plt.savefig('MyoConfusionMatrix')

# Loading Images
path_train  = '/train_set'
path_test   = '/test_set'
path_val    = '/val_set'

train_list  = os.listdir(path_train)
test_list   = os.listdir(path_test)
val_list    = os.listdir(path_val)

train_list.sort()
test_list.sort()
val_list.sort()

num_training_samples    = size(train_list)
num_testing_samples     = size(test_list)
num_validation_samples  = size(val_list)

matrix_train    = array([array(sio.loadmat(path_train + '/' + img)['image']).flatten() for img in train_list], 'f')
matrix_test     = array([array(sio.loadmat(path_test  + '/' + img)['image']).flatten() for img in test_list],  'f')
matrix_val      = array([array(sio.loadmat(path_val   + '/' + img)['image']).flatten() for img in val_list],   'f')

# Labeling
label_train = np.ones((num_training_samples,), dtype = int)

label_train[0      : 10848] = 0     #exercise 1  - E1 - index flexion 
label_train[10848  : 21696] = 1     #exercise 2  - E1 - ring flexion
label_train[21696  : 32544] = 2     #exercise 3  - E1 - thumb flexion

label_train[32544  : 43392] = 3     #exercise 4  - E2 - thumb up
label_train[43392  : 54240] = 4     #exercise 5  - E2 - abduction of all fingers
label_train[54240  : 65088] = 5     #exercise 6  - E2 - fingers flexed together in fist
label_train[65088  : 75936] = 6     #exercise 7  - E2 - fixed hook grasp
label_train[75936  : 86784] = 7     #exercise 8  - E2 - ring grasp

label_train[86784  :  97632] = 8    #exercise 9  - E3 - medium wrap
label_train[97632  : 108480] = 9    #exercise 10 - E3 - ring grasp
label_train[108480 : 119328] = 10   #exercise 11 - E3 - prismatic four finger grasp
label_train[119328 : 130176] = 11   #exercise 12 - E3 - writing tripod grasp

label_test = np.ones((num_testing_samples,), dtype = int)

label_test[0      :   3616] = 0   #exercise 1
label_test[3616   :   7232] = 1   #exercise 2 
label_test[7232   :  10848] = 2   #exercise 3

label_test[10848  :  14464] = 3   #exercise 4
label_test[14464  :  18080] = 4   #exercise 5
label_test[18080  :  21696] = 5   #exercise 6 
label_test[21696  :  25312] = 6   #exercise 7 
label_test[25312  :  28928] = 7   #exercise 8 

label_test[28928  :  32544] = 8   #exercise 9 
label_test[32544  :  36160] = 9   #exercise 10
label_test[36160  :  39776] = 10  #exercise 11 
label_test[39776  :  43392] = 11  #exercise 12 

label_val = np.ones((num_validation_samples,), dtype = int)

label_val[0      :   3616] = 0   #exercise 1
label_val[3616   :   7232] = 1   #exercise 2 
label_val[7232   :  10848] = 2   #exercise 3

label_val[10848  :  14464] = 3   #exercise 4
label_val[14464  :  18080] = 4   #exercise 5
label_val[18080  :  21696] = 5   #exercise 6 
label_val[21696  :  25312] = 6   #exercise 7 
label_val[25312  :  28928] = 7   #exercise 8 

label_val[28928  :  32544] = 8   #exercise 9 
label_val[32544  :  36160] = 9   #exercise 10
label_val[36160  :  39776] = 10  #exercise 11 
label_val[39776  :  43392] = 11  #exercise 12 

# Training set.
X_train, y_train = shuffle(matrix_train, label_train, random_state = 3)
# .. to images again! (For convolution)
img_rows = 8
img_cols = 15

X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)

X_train = np.transpose(X_train, (0,2,3,1))
# .. categorical labeling
num_classes = 12

Y_train= np_utils.to_categorical(y_train, num_classes)

# Test set.
X_test = matrix_test.reshape(matrix_test.shape[0], 1, img_rows, img_cols)

X_test = np.transpose(X_test, (0,2,3,1))
# .. categorical labeling
num_classes = 12

Y_test= np_utils.to_categorical(label_test, num_classes)
# Validation set.

X_val = matrix_val.reshape(matrix_val.shape[0], 1, img_rows, img_cols)

X_val = np.transpose(X_val, (0,2,3,1))
# .. categorical labeling
num_classes = 12

Y_val= np_utils.to_categorical(label_val, num_classes)

# Model             
model = Sequential()

# Stage 1
model.add(Conv2D(kernel_size=(3,4), strides=1, filters=32, padding='same',data_format = 'channels_last', name='layer_conv1', input_shape=(img_rows, img_cols, 1)))
model.add(Activation('relu'))

# Stage 2
model.add(Conv2D(kernel_size=(3,3), strides=1, filters=32, padding='same', name='layer_conv2'))
model.add(Activation('relu'))
model.add(Dropout(0.15))
model.add(MaxPooling2D(pool_size = 2, strides=1))

# Stage 3
model.add(Conv2D(kernel_size=(2,1), strides=1, filters=32, padding='same', name='layer_conv4'))
model.add(Activation('relu'))

# Stage 4
model.add(Conv2D(kernel_size=(1,3), strides=(1,2), filters=64, padding='same', name='layer_conv5'))
model.add(Activation('relu'))
model.add(Dropout(0.15))
model.add(MaxPooling2D(pool_size = 2, strides=(2,2)))

# Stage 5
model.add(Conv2D(kernel_size=(1,2), strides=1, filters=64, padding='same', name='layer_conv7'))
model.add(Activation('relu'))

# Stage 6
model.add(Conv2D(kernel_size=(2,2), strides=1, filters=128, padding='same', name='layer_conv8'))
model.add(Activation('relu'))
model.add(Dropout(0.15))

model.add(Flatten())

# Stage 7
model.add(Dense(units = 512))
model.add(Activation('relu'))
model.add(Dropout(0.25))

# Stage 8
model.add(Dense(units = 128))
model.add(Activation('relu'))
model.add(Dropout(0.25))

# Stage 9
model.add(Dense(units = 64))
model.add(Activation('relu'))
model.add(Dropout(0.25))

model.add(Dense(12))
model.add(Activation('softmax'))

model.summary()

# Optimizer
sgd = SGD(lr=0.01, decay=1e-6,  momentum=0.9, nesterov=False)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

# Fit
model.fit(x = X_train, y = Y_train, validation_data=(X_val, Y_val), epochs = 50, batch_size = 1024, verbose = 1, callbacks = [tensorboard])

# Evaluation
result = model.evaluate(x=X_test,y=Y_test)

for name, value in zip(model.metrics_names, result):
    print(name, value)
    
model.save('Myo_Armband_Model_Demo.h5')

# Confusion Matrix
rounded_predictions = model.predict_classes(X_test, batch_size = 1024, verbose = 0)
conf_matrix = confusion_matrix(Y_test, rounded_predictions)

cm_plot_labels = ['index finger flexion', 'ring finger flexion', 'thumb extension', 'thumb up', 'index-middle extension','abduction of all fingers', 'fist', 'pointing index', 'bottle grasp', 'ring grasp', 'prismatic four finger grasp', 'writing tripod grasp']

plot_confusion_matrix(conf_matrix, cm_plot_labels, title = 'Confusion Matrix')
  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 手势识别是一种通过分析人体运动信号来识别特定手势的技术。而SEM信号,即肌电信号,是一种记录肌肉活动的生物电信号。 MATLAB作为一种强大的编程工具,可以用于SEM信号的处理和手势识别任务。在MATLAB中,可以使用各种函数来处理SEM信号。首先,需要通过传感器采集SEM信号,并通过滤波器去除噪声。接下来,可以使用时域分析方法,如平均值、均方根等,来提取SEM信号的特征。此外,还可以使用频域分析方法,如傅里叶变换,来获取SEM信号的频谱特征。 一旦获得了SEM信号的特征,就可以使用分类算法进行手势识别。常用的分类算法包括支持向量机、人工神经网络等。这些算法可以通过训练数据集进行学习和训练,然后通过测试数据集验证其准确性。 在MATLAB中,可以使用分类模型工具箱来实现不同的手势识别算法。通过这些工具箱提供的函数和接口,可以方便地构建和训练分类模型,并进行手势识别任务的实时预测。 总之,MATLAB基于SEM信号的手势识别包括SEM信号的处理和特征提取,以及分类算法的应用和训练。通过这些步骤,可以实现对不同手势的准确识别,并为相关应用提供实时响应和控制。 ### 回答2: 手势识别是通过对手部动作进行分析和识别,以实现人机交互的一种技术。MATLAB 是一种常用的编程语言和环境,可以用于处理和分析信号数据。 基于表面肌电信号(surface electromyography,SEMG)的手势识别算法可以通过收集和分析肌电信号来实现。SEMG 信号是通过在肌肉表面放置电极来测量和记录肌肉活动。 手势识别过程可以分为以下几个步骤: 1. 数据采集:通过连接肌电传感器,从用户的手部肌肉收集SEMG信号数据。这些传感器可以将肌肉活动转换为电信号,并将其传递给计算机进行进一步处理。 2. 信号预处理:对采集到的肌电信号进行预处理,包括滤波、去噪和信号增强等操作。这可以有效减少噪声和提高信号的质量。 3. 特征提取:从预处理的信号中提取特征,这些特征可以表示不同手势的模式和特征。常用的特征提取方法包括时域特征、频域特征和时频域特征等。 4. 手势分类:将提取的特征输入到分类器中进行分类和识别。常见的分类器包括支持向量机、人工神经网络和决策树等。分类器训练的目标是建立一个能将特征与手势标签相关联的模型。 5. 手势识别:根据分类器的结果,对新的肌电信号进行识别和分类,从而确定用户执行的手势。 MATLAB提供了丰富的信号处理和机器学习工具箱,可以用于处理和分析SEMG信号,并实现手势识别算法。借助MATLAB的强大功能,我们可以轻松完成信号预处理、特征提取、分类器训练和手势识别等步骤。 总体而言,MATLAB基于SEMG信号的手势识别可以为我们提供一种快速、准确并且实用的手势交互方式,能够广泛应用于虚拟现实、医疗康复和智能设备等领域。 ### 回答3: 手势识别是指通过对手部运动的感知和分析,识别出手势所代表的意图或动作。MATLAB是一种强大的计算软件,具有丰富的信号处理工具和算法库,可以用于基于表面肌电信号sEMG)的手势识别sEMG是通过电极贴附在皮肤表面来记录肌肉电活动的信号。首先,我们需要获取sEMG信号。可以使用MATLAB中的信号采集工具箱,连接合适的传感器和硬件设备,实时采集sEMG信号数据。 接下来,对采集到的sEMG信号进行预处理。预处理包括滤波、降噪和特征提取。可以利用MATLAB提供的滤波算法、降噪方法和特征提取函数,对sEMG信号进行数据清洗和特征提取。常用的特征包括幅值、能量、时域相关系数等。 针对特定手势,我们需要建立手势模型。可以使用MATLAB的模式识别工具箱,选择合适的分类算法(如支持向量机、人工神经网络等),对特征向量进行训练和建模。这样可以建立手势模型,用于后续的手势识别。 最后,对于新的未知手势,我们可以将其sEMG信号输入已经训练好的手势模型,通过模型识别手势。可以利用MATLAB的模型预测函数,将预处理后的特征向量输入到模型中,得到手势识别的结果。 综上所述,MATLAB可以通过信号采集、预处理、特征提取、模型训练和手势识别等步骤,实现基于sEMG信号的手势识别。其丰富的功能和强大的分析能力使得MATLAB成为进行手势识别研究和应用的理想工具。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mr Robot

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

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

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

打赏作者

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

抵扣说明:

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

余额充值