「scipy、eeg」使用python scipy butter filtfilt 分解EEG数据为5个频带和滤波参数选择

87 阅读2分钟

使用scipy butter filtfilt 分解EEG数据和滤波参数

【目录】

  • EEG数据频带和滤波参数
  • 滤波类型及示例
  • Pyhton 代码实现

一、EEG数据频带和滤波参数

脑电波分类及滤波参数.png

二、滤波类型

  • 低通滤波(lowpass)
  • 高通滤波(highpass)
  • 带通滤波(bandpass)
  • 带阻滤波(bandstop)

2.1 低通滤波

低于某个频率的信号可以通过,而高于这个频率的信号会被衰减过滤掉

2.2 高通滤波

高于某个频率的信号可以通过,而低于这个频率的信号会被衰减过滤掉

2.3 带通滤波

指的是在某个频率段范围内的信号可以通过,而这个频率段范围以外的信号会被衰减过滤掉

2.4 带阻滤波

指的是在某个频率范围内的信号会被衰减过滤掉,而这个频率范围以外的信号会被保留下来

tips:滤波并不能完全过滤出我们想要的频段。比如30Hz的低通滤波,并不是说30Hz以外的信号就全部 被过滤掉了,而是以30Hz为截止频率,高于这个截止频率的信号会被逐渐衰减。

滤波器种类.png

三、Python 代码实现

  • scipy
  • butter
  • filtfilt,对于EEG数据,推荐filtfilt
 import numpy as np
 from scipy.signal import butter, filtfilt
 ​
 ​
 def decompose_eeg_data(data, sample_rate=250):
     """
     decompose eeg data to five band:
         'delta': (1, 4),
         'theta': (4, 8),
         'alpha': (8, 13),
         'beta': (13, 30),
         'gamma': (30, 40)
     :param data: raw eeg data, format = (channels, timepoints)
     :param sample_rate: sampling rate of data
     :return: decomposed eeg data
     """
 ​
     # define band
     frequency_bands = {
         'delta': (1, 4),
         'theta': (4, 8),
         'alpha': (8, 13),
         'beta': (13, 30),
         'gamma': (30, 40)
     }
 ​
     data_matrix = []
     for item in frequency_bands.values():
         data_matrix.append(butter_bandpass(data, 5, item, sample_rate))
 ​
     return np.array(data_matrix)
 ​
 ​
 def butter_bandpass(data, order, freq_cut, sample_rate):
     """
     btype: lowpass, highpass, bandpass, bandstop.
             低通、高通、带通、带阻
     low order -> [1, 3]
         通常用于简单的滤波需求,如基础的信号去噪或低频信号的保留.
         例如,1阶滤波器相对平滑,适合对信号变化不那么敏感的情况。
     middle order -> [4, 6]
         通常用于对频率响应有一定要求的应用。
         比如在图像处理或生物信号处理(如 EEG、ECG)中,4-6阶可以在有效过滤噪声的同时
         保留信号的特征。
     high order -> [7, 7+]
         只有在信号特点复杂、需要更加精准的频率选择时使用。
         高阶滤波器可以产生更陡峭的过渡带,但可能提高计算复杂性和引入更大的相位延迟。
         一般考虑在 7-10 阶,但如果需要更严格的频率响应,甚至可以用到 20 阶或以上,
         但这通常不建议,因为稳定性和计算负担会显著增加。
     :param data: raw data is going to filter
     :param order: the order of filter
     :param freq_cut: [low, high] cut frequency
     :param sample_rate: sampling rate of data
     :return: filtered data
     """
     low = freq_cut[0] * 2 / sample_rate
     high = freq_cut[1] * 2 / sample_rate
     b, a = butter(order, [low, high], btype='bandpass', fs=sample_rate)
     return filtfilt(b, a, data)  # 双向滤波