EMG 信号处理
状态: 🚧 Work In Progress
EMG (肌电图) 是 Movement Chain AI 的核心差异化技术。本页面将详细解释 EMG 信号处理的技术细节。
🤔 什么是 EMG?
EMG = Electromyography (肌电图)
简单来说:肌肉收缩时会产生微弱的电信号,EMG 传感器能检测到这些信号。
肌肉收缩 → 电信号 → EMG 传感器 → 数字信号 → 我们的算法📊 EMG 信号的特点
原始信号很嘈杂
原始 EMG: ∿∿∿∿∿∿∿∿∿∿∿∿∿∿∿∿∿∿
(高频噪声,难以分析)为什么嘈杂?
- 肌肉是多个肌纤维的集合
- 每根纤维独立放电
- 信号叠加产生随机噪声
需要信号处理
原始信号 → [处理] → 清晰包络
∿∿∿∿∿∿∿ ___/‾‾‾\___🛠️ 信号处理流程
步骤 1: 整流 (Rectification)
取绝对值,把负值变成正值:
python
emg_rect = np.abs(emg_signal)为什么?
- 原始信号有正有负
- 我们只关心"激活强度",不关心方向
- 整流后信号全是正的
步骤 2: RMS 包络 (Root Mean Square)
用滑动窗口计算均方根:
python
window_size = int(emg_rate * 0.05) # 50ms 窗口
rms = np.sqrt(
np.convolve(
emg_rect**2,
np.ones(window_size) / window_size,
mode='same'
)
)为什么用 RMS?
- 平滑信号,去除高频噪声
- 保留激活强度信息
- 运动科学的标准做法
窗口大小为什么是 50ms?
- 太小(如 10ms): 噪声还在
- 太大(如 200ms): 细节丢失
- 50ms: 经验最佳值
步骤 3: 归一化 (Normalization)
归一化到 0-1:
python
rms_norm = rms / np.max(rms)为什么归一化?
- 不同人的 EMG 幅度差异很大
- 肌肉量大的人信号强
- 归一化后可以比较不同人
🎯 肌肉激活检测 (Onset Detection)
目标
找到肌肉"开始激活"的时刻。
方法: 阈值法
python
def detect_muscle_onset(emg_signal, emg_rate, threshold=0.1):
# 1-3. 整流 + RMS + 归一化
rms_norm = process_emg(emg_signal, emg_rate)
# 4. 找到第一次超过阈值的点
crossings = np.where(rms_norm > threshold)[0]
if len(crossings) == 0:
return None
onset_frame = crossings[0]
onset_time = onset_frame / emg_rate
return onset_time阈值选择
| 阈值 | 效果 |
|---|---|
| 0.05 | 太敏感,噪声也会触发 |
| 0.10 | ✅ 标准值,平衡敏感度和准确性 |
| 0.30 | 太迟钝,错过真实激活 |
📐 运动链分析
肌肉分组
跳跃数据的 9 个 EMG 通道:
通道 0-2: 下肢 (腿部肌肉)
通道 3-5: 核心 (腹肌、背肌)
通道 6-8: 上肢 (手臂肌肉)检测顺序
python
# 检测每组的平均激活时间
leg_onset = np.mean([
detect_onset(emg[:, 0]),
detect_onset(emg[:, 1]),
detect_onset(emg[:, 2])
])
core_onset = np.mean([
detect_onset(emg[:, 3]),
detect_onset(emg[:, 4]),
detect_onset(emg[:, 5])
])
arm_onset = np.mean([
detect_onset(emg[:, 6]),
detect_onset(emg[:, 7]),
detect_onset(emg[:, 8])
])
# 检查顺序
if core_onset < leg_onset:
print("❌ 倒序运动链!")🎓 高级话题 (待完善)
- MVC (Maximum Voluntary Contraction) 归一化
- 频域分析 (FFT)
- 肌肉疲劳检测
- 多通道协同分析
📚 参考资料
- Phase 0: 证明核心价值 - 实战案例
- 运动链分析 - 更多背景
当前状态: 基础内容已完成,高级话题待补充
这个页面会随着项目进展持续更新。