4. 数据分割与标准化:步态周期分割、时间归一化、幅度归一化

好,咱们接着聊。上一节我们把原始肌电信号处理干净了,去噪、滤波、整流、平滑,一套组合拳打完。但这时候的数据,还不能直接拿去算肌肉协同。

为什么?你想想看,不同人的步态周期长度不一样,有人走一步0.8秒,有人1.2秒。不同人发力大小也不一样,有人轻轻一蹬就100% MVC,有人拼尽全力也就那样。这些差异如果不处理,算出来的协同模式根本没法比较。

所以,数据分割和标准化,是绕不开的一步。我个人习惯把这步叫做「让数据对齐说话」。

4.1 步态周期分割:找到重复的节拍

步态分析里,最基本的分割单位就是「步态周期」。一个完整的步态周期,从一侧足跟着地开始,到同侧足跟再次着地结束。

为什么要分割?因为肌肉协同提取算法(比如NMF)需要多个周期的数据作为输入。你拿一个周期去算,样本量不够,结果不稳定。拿10个、20个周期去算,协同模式才可靠。

分割的方法主要有三种:

  • 基于足底压力:用测力台或压力鞋垫,检测足跟着地时刻。这是金标准,精度高,但设备贵。
  • 基于运动学:用动作捕捉系统,看脚踝或足跟的标记点轨迹。我早期项目里常用这个,因为实验室有Vicon系统。
  • 基于加速度计:在脚踝或腰部绑一个IMU,检测加速度的峰值。这个方法便携,适合户外或临床场景。

关键点:分割的精度直接影响后续分析。我曾经在一个项目中,因为足跟着地检测阈值设得太松,导致一个周期里包含了两个步态周期,结果协同模式多出来一个没意义的成分。嗯,从那以后我每次都会手动检查分割结果。

分割完成后,你会得到N个步态周期的肌电数据。每个周期的长度可能不一样,比如有的人走得快,有的人走得慢。这时候就需要时间归一化。

4.2 时间归一化:把不同长度的周期拉齐

时间归一化,说白了就是把每个步态周期「拉伸」或「压缩」到相同的长度。最常见的做法是归一化到100%步态周期,也就是0%到100%,每个点代表一个百分比位置。

常用的插值方法:

  • 线性插值:简单快速,适合数据点密集的情况。我一般先用这个。
  • 三次样条插值:更平滑,适合数据点稀疏或需要保留曲线细节的情况。但要注意,样条插值可能会在端点处产生过冲。

下面是我常用的Python代码片段,用scipy做时间归一化:

import numpy as np
from scipy import interpolate

def time_normalize(emg_cycle, target_length=100):
    """
    将单个步态周期的肌电信号归一化到目标长度
    emg_cycle: 1D array, 原始周期数据
    target_length: 目标长度,默认100个点
    """
    original_length = len(emg_cycle)
    original_x = np.linspace(0, 1, original_length)
    target_x = np.linspace(0, 1, target_length)
    
    # 线性插值
    f = interpolate.interp1d(original_x, emg_cycle, kind='linear')
    normalized_cycle = f(target_x)
    
    return normalized_cycle

# 使用示例
normalized_emg = time_normalize(raw_cycle, target_length=101)  # 0%到100%,共101个点

我的经验:归一化到101个点(0到100%)比100个点更直观,因为100%对应最后一个点,方便后续画图时标注。另外,记得检查插值后的数据是否在合理范围内,别出现负值或异常尖峰。

4.3 幅度归一化:消除个体差异

时间归一化解决了「长度不一致」的问题,但「幅度不一致」的问题还在。不同人的肌肉力量不同,同一人在不同天的发力状态也不同。如果不做幅度归一化,算出来的协同权重会受绝对幅值影响,没法跨被试比较。

最常用的幅度归一化方法是最大等长收缩(MVC)归一化

具体做法:

  1. 在正式实验前,让受试者做该肌肉的最大等长收缩动作,记录3-5秒的肌电信号。
  2. 对MVC信号做同样的预处理(滤波、整流、平滑)。
  3. 取MVC信号的最大值(或平均值,我习惯用最大值),作为该肌肉的参考值。
  4. 将步态周期中每个时间点的肌电幅值,除以这个参考值。

公式很简单:

normalized_emg = raw_emg / mvc_value

归一化后的值在0到1之间(偶尔会超过1,如果步态中的发力超过了MVC测试时的发力,但这种情况很少见)。

避坑指南:我曾经在一个项目中,MVC测试时没有给受试者足够的休息时间,导致MVC值偏低。结果步态数据归一化后,很多值都超过了1,看起来像肌肉一直在超负荷工作。后来重新测了MVC,问题才解决。所以,MVC测试一定要让受试者充分休息,至少休息1-2分钟。

除了MVC归一化,还有几种替代方法:

  • 峰值归一化:用步态周期内的最大值做分母。好处是不需要额外测MVC,但缺点是不同周期的峰值可能不同,导致归一化结果不稳定。
  • 均值归一化:用步态周期内的平均值做分母。适合比较不同肌肉之间的相对激活模式。
  • Z-score标准化:减去均值,除以标准差。适合做统计比较,但会丢失幅值的绝对信息。

我个人推荐:如果条件允许,优先用MVC归一化。它最符合生理意义,也最容易被审稿人接受。

4.4 本章知识体系总览

下面这张图,把数据分割与标准化的流程串起来了。你可以把它当作一个检查清单,做分析时对照着来。

数据分割与标准化流程 原始EMG信号 步态周期分割 方法:足底压力 | 运动学 | 加速度计 时间归一化 目标:0%~100%步态周期(101个点) 方法:线性插值 / 三次样条插值 幅度归一化 方法:MVC归一化 | 峰值归一化 | 均值归一化

这张图里,从原始信号到步态周期分割,再到时间归一化,最后到幅度归一化,每一步都有明确的方法和注意事项。你按照这个流程走,基本不会出大问题。

最后提醒一句:数据分割和标准化,看似是预处理中的「体力活」,但恰恰是决定分析成败的关键。我见过太多论文,因为这一步没做好,导致后续的协同分析结果不可靠。所以,别嫌麻烦,每一步都检查一遍。

专注资料整理