3、肌电信号预处理:滤波去噪(带通、陷波)、基线校正、整流与平滑

好,咱们直接进入正题。肌电信号这东西,说白了就是肌肉收缩时产生的微弱电信号。你想想看,直接从皮肤表面采集到的信号,那叫一个“脏”——工频干扰、运动伪迹、心电串扰,啥都有。如果不做预处理,后续的分析就是“垃圾进,垃圾出”。

我个人习惯把预处理分成四个核心步骤:滤波去噪、基线校正、整流、平滑。每一步都有它的道理,咱们一个一个拆开讲。

3.1 滤波去噪:把“脏东西”筛掉

肌电信号的有效频率范围,一般在 20 Hz 到 500 Hz 之间。低于 20 Hz 的,大多是运动伪迹(比如电极线晃动);高于 500 Hz 的,基本是高频噪声。所以,第一步就是用一个带通滤波器,把 20-500 Hz 以外的成分统统干掉。

核心参数:

  • 高通截止频率: 10-20 Hz(去除运动伪迹)
  • 低通截止频率: 450-500 Hz(去除高频噪声)
  • 滤波器阶数: 4 阶或 8 阶 Butterworth(巴特沃斯)最常用,通带平坦,过渡带适中

嗯,这里要注意:陷波滤波器。国内市电是 50 Hz,国外是 60 Hz。这个频率的干扰会直接叠加在肌电信号上,肉眼可见一条粗线。我建议用 48-52 Hz 的陷波,把 50 Hz 及其附近频率都干掉。别只陷 50 Hz 一个点,因为实际干扰会有频偏。

避坑指南: 我曾经在一个项目中,只用了带通滤波,没加陷波。结果提取的肌电特征值总是偏大,后来发现是 50 Hz 工频干扰没滤干净,导致 RMS 值虚高。从那以后,我只要用市电供电的设备,必加陷波。

代码实现(Python 示例,用 scipy):

from scipy import signal

# 设计带通滤波器:20-500 Hz,4阶 Butterworth
b, a = signal.butter(4, [20, 500], btype='bandpass', fs=1000)
emg_filtered = signal.filtfilt(b, a, emg_raw)

# 设计陷波滤波器:50 Hz,品质因数 Q=30
b_notch, a_notch = signal.iirnotch(50, 30, 1000)
emg_notched = signal.filtfilt(b_notch, a_notch, emg_filtered)

3.2 基线校正:让信号“归零”

滤波之后,信号可能还存在一个直流偏置。说白了,就是信号整体往上或往下飘了。这通常是因为电极与皮肤之间的接触电位差,或者放大器本身的零点漂移。

怎么做?很简单:计算信号的平均值,然后减去它。这样信号就围绕 0 上下波动了。

我的习惯: 在采集静息状态(肌肉完全放松)下的信号,取 1-2 秒的均值作为基线。然后整个信号都减去这个基线值。这样能最大程度消除个体差异和电极放置的影响。

# 基线校正:减去均值
baseline = np.mean(emg_notched[0:1000])  # 取前1秒作为基线
emg_baselined = emg_notched - baseline

3.3 整流:把负半周翻上来

肌电信号是双极性的,有正有负。但咱们关心的是信号的幅值大小,而不是方向。所以,需要把负半周翻到正半周来。这就是全波整流

你想想看,如果不整流,直接取平均,正负抵消,结果接近 0,啥也看不出来。整流之后,所有值都是正的,才能反映肌肉的激活程度。

全波整流公式: emg_rectified = abs(emg_baselined)

# 全波整流
emg_rectified = np.abs(emg_baselined)

3.4 平滑:提取包络线

整流后的信号,虽然都是正的,但依然很“毛糙”,像锯齿一样。我们需要提取它的包络线,也就是信号的轮廓。常用的方法有两种:

  • 移动平均(Moving Average): 简单粗暴,计算窗口内的均值。窗口长度一般取 50-200 ms。
  • 低通滤波: 用 3-10 Hz 的低通滤波器,直接滤掉高频波动,留下低频包络。

我个人更推荐低通滤波,因为它不会像移动平均那样产生相位延迟(如果用零相位滤波的话)。

经验值: 对于步态分析,我常用 6 Hz 的低通滤波。对于抓握等精细动作,可以提高到 10 Hz。太低了会丢失细节,太高了包络不平滑。

# 低通滤波平滑:6 Hz,4阶 Butterworth
b_lp, a_lp = signal.butter(4, 6, btype='low', fs=1000)
emg_envelope = signal.filtfilt(b_lp, a_lp, emg_rectified)

知识体系总览

下面这张图,把整个预处理流程串起来了。你可以把它当作一个检查清单,每次处理肌电数据时,按这个顺序走一遍,基本不会出错。

肌电信号预处理流程 原始肌电信号 滤波去噪 带通 + 陷波 基线校正 减去均值 整流 全波整流 平滑 低通滤波 预处理完成 关键参数 带通:20-500 Hz 陷波:48-52 Hz 平滑:6-10 Hz

小结一下

预处理这四步,顺序不能乱。先滤波去噪,再基线校正,然后整流,最后平滑。每一步都依赖上一步的结果。我见过有人先整流再滤波,结果把噪声也整流了,后面怎么滤都滤不干净。

嗯,最后提醒一句:参数不是死的。不同肌肉、不同动作、不同采集设备,参数可能需要微调。比如,面部肌电信号频率偏高,带通可以设到 30-600 Hz;而躯干肌电信号频率偏低,高通可以降到 10 Hz。多试几次,找到最适合你数据的参数组合。


专注资料整理