当前位置: 首页 > news >正文

利用Myo臂环采集肌电信号和角速度来实现实时手势识别

利用Myo臂环采集肌电信号(EMG)和角速度(来自陀螺仪)来实现实时手势识别

一、系统概述与工作原理

Myo臂环是一款可穿戴设备,它包含:

  1. 8个EMG传感器:测量前臂肌肉产生的电信号。不同的手势会激活不同的肌肉群,产生独特的肌电模式。
  2. 9轴IMU:包含陀螺仪(角速度)、加速度计和磁力计,用于捕捉手部的运动和朝向。

核心思想:将EMG和角速度等多模态数据融合,通过机器学习算法训练一个分类模型,从而实时识别出执行的手势。


二、技术流程详解

1. 数据采集与预处理

  • 连接Myo:使用Myo的SDK(MATLAB支持通过Myo SDK的MEX包装器)建立连接。
  • 数据流:同时订阅EMG和IMU(陀螺仪)数据流。
  • 预处理
    • EMG:通常应用一个带通滤波器(如20-450 Hz)来去除直流偏移和高频噪声。
    • 陀螺仪:数据通常已经比较平滑,有时需要进行校准以去除零偏。

2. 数据分割(用于训练)

实时识别需要处理连续的数据流。通常采用滑动窗口方法:

  • 窗口长度:200-300 ms(平衡实时性和信息量)。
  • 窗口重叠:50%的重叠率很常见,这能提高响应速度,确保不会在窗口边缘错过手势。

3. 特征提取

这是最关键的一步。从每个数据窗口中提取特征,以降低维度并捕获模式。

对于EMG信号(每个通道提取特征,共8通道):

  • 时域特征(计算速度快,适合实时系统):
    • 平均值:信号的平均能量。
    • 标准差:信号的幅度变化。
    • 积分肌电值:信号的绝对值的和或积分。
    • 过零率:信号穿过零点的次数。
    • 威尔逊振幅:信号一阶差分绝对值的平均值。
  • 频域特征(计算量稍大):
    • 中值频率平均频率(需对信号进行FFT)。

对于陀螺仪信号(每个轴X, Y, Z提取特征):

  • 均值:平均角速度。
  • 标准差:角速度的变化量。
  • 峰值:窗口内的最大角速度。
  • 信号幅度面积:角速度绝对值的积分。

最终,对于一个数据窗口,你会得到一个长长的特征向量(例如,8个EMG通道 * 4个特征 + 3个陀螺仪轴 * 3个特征 = 41个特征)。

4. 模型训练(离线阶段)

  1. 数据收集:录制每个手势(例如,握拳、张开、手腕左旋、手腕右旋、休息)的多组数据。
  2. 标注:为录制的每一段数据打上标签(如 1=握拳, 2=张开...)。
  3. 特征提取:对每个窗口的数据进行上述特征提取,形成特征矩阵和标签向量。
  4. 训练分类器:使用特征矩阵和标签来训练一个机器学习模型。常用且高效的算法有:
    • 支持向量机:在小数据集上表现优异,非常受欢迎。
    • 随机森林:抗过拟合能力强,性能稳定。
    • LDA:计算量小,速度快,适合实时系统。

5. 实时识别(在线阶段)

  1. 实时获取数据并放入滑动窗口。
  2. 对窗口内的最新数据提取相同的特征
  3. 将特征向量输入到已训练好的模型中。
  4. 模型输出一个预测的手势标签。
  5. 根据识别出的手势执行相应操作(如控制机器人、虚拟鼠标等)。

三、MATLAB 实现代码

步骤 1: 离线训练模型

% 假设你已经录制并加载了数据
% load('training_data.mat'); 
% trainingData: N x Features 矩阵
% trainingLabels: N x 1 标签向量% 使用随机森林训练分类模型
rng(1); % 控制可重复性
model = TreeBagger(100, trainingData, trainingLabels, ...'Method', 'classification', ...'OOBPrediction', 'on', ...'MinLeafSize', 5);% 或者使用SVM
% model = fitcecoc(trainingData, trainingLabels);% 评估模型(使用留出法或交叉验证)
[predictions, scores] = model.predict(trainingData);
accuracy = sum(predictions == trainingLabels) / numel(trainingLabels);
fprintf('Training Accuracy: %.2f%%\n', accuracy * 100);% 保存模型
save('my_gesture_model.mat', 'model');

步骤 2: 实时识别循环

function realTimeRecognition()% 加载预训练模型load('my_gesture_model.mat', 'model'); % 初始化Myo连接mm = MyoMex(); myo = mm.myoData;% 参数设置windowLength = 200; % 200ms 窗口sampleRate = 200; % Myo EMG采样率约为200HzwindowSize = round(windowLength / 1000 * sampleRate); % 计算窗口点数overlap = round(windowSize * 0.5); % 50% 重叠bufferEMG = zeros(windowSize, 8); % 环形缓冲区存储EMGbufferGyro = zeros(windowSize, 3); % 环形缓冲区存储Gyroindex = 1;h = figure; stop = false;disp('Starting real-time recognition. Press any key to stop.');% 主循环while ishghandle(h) && ~stop% 获取最新数据latestEMG = myo.emg_log; latestGyro = myo.rotational_velocity_log;if ~isempty(latestEMG)% 将新数据填入缓冲区(模拟实时流)for i = 1:size(latestEMG, 1)bufferEMG(index, :) = latestEMG(i, :);bufferGyro(index, :) = latestGyro(i, :);index = mod(index, windowSize) + 1; % 环形索引% 每当缓冲区填满一个“步长”后就进行一次预测if index == overlap % 1. 获取当前窗口数据(需要处理环形缓冲区的索引)windowEMG = [bufferEMG(index:end, :); bufferEMG(1:index-1, :)];windowGyro = [bufferGyro(index:end, :); bufferGyro(1:index-1, :)];% 2. 特征提取 (这里简化了,实际需要为每个通道计算)features = [];for ch = 1:8 % EMG特征sig = windowEMG(:, ch);features = [features, mean(sig), std(sig), mean(abs(sig))]; endfor ax = 1:3 % Gyro特征sig = windowGyro(:, ax);features = [features, mean(sig), std(sig)]; end% 3. 进行预测[gestureLabel, scores] = predict(model, features);gestureStr = string(gestureLabel);confidence = max(scores);% 4. 显示结果clf;text(0.5, 0.7, gestureStr, 'FontSize', 30, 'HorizontalAlignment', 'center');text(0.5, 0.3, sprintf('Conf: %.2f', confidence), 'FontSize', 20, 'HorizontalAlignment', 'center');drawnow;% 5. 这里可以添加控制逻辑: % if gestureStr == "fist", ... endendendendpause(0.01); % 短暂暂停,避免占用100% CPUstop = ~isempty(get(h,'CurrentCharacter')); enddelete(mm); % 断开Myo连接close(h);
end

参考代码 利用myo采集肌电信号和角速度信息,实现实时的手势识别 www.youwenfan.com/contentcng/53663.html

四、挑战与改进建议

  1. 个性化与校准:不同用户的肌肉信号差异很大。最好为每个用户单独收集数据并训练模型,或使用迁移学习来适配新用户。
  2. 手势设计:选择在EMG和运动模式上差异明显的手势,以提高识别率。例如,“握拳” vs. “张开” vs. “手腕左旋”是很好的选择。
  3. 疲劳和位移:长时间使用后,肌肉疲劳或臂环稍微转动都会导致信号漂移。可以考虑加入在线自适应机制,定期更新模型。
  4. 数据同步:确保EMG和陀螺仪数据的时间戳对齐。
  5. 延迟优化:在MATLAB中实现真正的低延迟实时处理具有挑战性。对于性能要求极高的应用,可以考虑用C++实现核心算法。

这个项目完美地结合了硬件交互、信号处理和机器学习,是学习嵌入式ML的一个绝佳实践。祝你成功!

http://www.wxhsa.cn/company.asp?id=4774

相关文章:

  • 实用指南:leetcode 966. 元音拼写检查器 中等
  • 三轴传感开发新纪元:exvib扩展库让精准检测触手可及!
  • List与Dictionary区别
  • OpenStack Cinder 架构
  • 完整教程:IC(输入捕获)
  • HiMarket 正式开源,为企业落地开箱即用的 AI 开放平台
  • 如何统计DrawMeshInstancedIndirect绘制物体的Triangle数据
  • VK1S68C点钟LED驱动控制专用芯片高抗干扰数显驱动IC 可支持134的点阵LED显示面板
  • 基于MATLAB的海洋中尺度涡旋诊断
  • 从混乱到有序:Tita 项目一体化管理的全场景赋能
  • SpringBoot入门指南:让Java开发变得像搭积木一样简单 - 教程
  • 汇编语言[王爽]-13 int指令【中断实现loop、jmp】
  • Supabase云同步架构:Flutter应用的数据同步策略
  • 汇编语言[王爽]-12 内中断
  • 【SPIE出版】第五届先进制造技术与电子信息国际学术会议(AMTEI 2025)
  • 2025.9.15 考试总结
  • 汇编语言[王爽]-01 基础知识
  • 贪心外套计数
  • 汇编语言[王爽]-02 寄存器
  • 汇编语言[王爽]-03 寄存器(内存访问)
  • 汇编语言[王爽]-05 [BX]和loop指令
  • 完整教程:YOLO数据集格式转换工具v1.0-微智启软件工作室
  • 2.docker 安装
  • 树形DP2F
  • 搞定SPI开发:硬件设计精讲与CH390H示例应用
  • Qt-摄像头捕获画面
  • 我开发的软件和开源/免费软件
  • PostgreSQL中级认证,PG证书官网查询
  • LLaMA-Adapter - 详解
  • 查看安装软件版本的命令