EMG数据FFT处理代码正确性及低频峰值问题求助
肌电(EMG)数据FFT分析问题求助
一、已完成的操作与代码
1. 原始与滤波后信号可视化
已完成0Hz滤波处理,使用以下代码绘制信号曲线:
plt.figure(figsize=(20,10)) sns.lineplot(data = DF_newemg, x = DF_newemg.index, y = 'emg[2]', label = 'DF_newemg') sns.lineplot(data = DF_newemg_filtered, x = DF_newemg_filtered.index, y = 'emg[2]', label = 'DF_newemg_filtered') plt.show()
结果说明:展示了原始EMG信号与0Hz滤波后信号的时域对比曲线。
2. FFT频谱提取与绘制
采用以下代码提取正频率分量并绘制频谱:
fs = 1000 from scipy.fft import fft, fftfreq N = len(DF_newemg_filtered['emg[0]']) freqs = fftfreq(N, d=1/fs) fft_values = fft(DF_newemg_filtered['emg[0]'].to_numpy()) positive_freqs = freqs[:N // 2] fft_values = abs(fft_values[:N//2]) plt.plot(positive_freqs, fft_values, label='Filtered Signal Spectrum', color='blue')
结果说明:绘制了滤波后EMG信号的正频率频谱图,出现0Hz及0~100Hz区间高峰值。
二、遇到的问题
- 频谱中0Hz及0~100Hz区间出现异常高峰值(设备已自带50Hz陷波滤波器)
- 不确定FFT结果的Y轴数值是否符合物理意义
三、问题分析与解决建议
针对0Hz及0~100Hz高峰值的处理
0Hz成分残留:
- 检查0Hz滤波的具体实现:若使用高通滤波,确认截止频率是否合理(建议设置为1Hz,彻底滤除直流偏移);若滤波阶数过低,会导致直流分量残留,可适当提高滤波阶数(比如4阶巴特沃斯高通)。
- 排查信号采集伪迹:EMG信号的低频峰值可能来自电极移动、肌肉静息时的基线漂移,需确认采集过程中电极是否固定良好、受试者是否保持稳定姿态。
0~100Hz高峰值:
- 50Hz陷波的局限性:设备自带的陷波滤波器可能仅针对50Hz基波,未覆盖100Hz二次谐波,可额外添加100Hz陷波滤波。
- 确认EMG信号正常能量分布:肌电信号的主要能量集中在20500Hz区间,0100Hz有一定幅值属于正常情况,但如果峰值过高,需排查是否存在电源杂散干扰、电极接触不良等问题。
关于FFT Y轴数值的正确性修正
当前代码直接取FFT的绝对值,未做幅值归一化,导致Y轴数值不具备物理意义。修正方法如下:
fs = 1000 from scipy.fft import fft, fftfreq N = len(DF_newemg_filtered['emg[0]']) freqs = fftfreq(N, d=1/fs) fft_values = fft(DF_newemg_filtered['emg[0]'].to_numpy()) # 提取正频率并做幅值归一化 positive_freqs = freqs[:N // 2] fft_amp = abs(fft_values[:N//2]) if N % 2 == 0: # 偶数点:直流分量单独除以N,其余除以N/2 fft_amp[0] = fft_amp[0] / N fft_amp[1:] = fft_amp[1:] / (N/2) else: # 奇数点:所有分量除以(N-1)/2 fft_amp = fft_amp / ((N-1)/2) plt.plot(positive_freqs, fft_amp, label='Filtered Signal Spectrum (Normalized)', color='blue') plt.ylabel('Amplitude') plt.xlabel('Frequency (Hz)') plt.legend() plt.show()
验证方法:生成已知参数的测试信号(如100Hz、幅值为1的正弦波),用上述代码做FFT,若对应频率点的幅值接近1,则说明归一化正确。
内容的提问来源于stack exchange,提问作者이다은
相关产品推荐
相关产品推荐

