Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SSVEP 脑机接口识别算法说明

本目录实现的是一个用于稳态视觉诱发电位(SSVEP, Steady-State Visual Evoked Potential)的目标频率识别程序。算法输入 EEG 脑电信号,输出每个 taskID 对应的刺激类别 stimID,取值范围为 0-7,对应刺激频率 [8, 9, 10, 11, 12, 13, 14, 15] Hz

文件说明

  • ssvepdetect.py:核心识别算法,包含滤波、参考模板构造、CCA/FBCCA 计算和分类逻辑。
  • demo.py:数据读取、按 taskID 分组、调用识别器预测、生成结果文件。
  • FinalResults/:整理后的最终预测结果。
  • FinalResults.zip:最终结果压缩包。

技术栈

  • Python 3.11
  • NumPy:矩阵运算、数组处理、正余弦模板生成。
  • SciPy Signal:50Hz 陷波滤波、椭圆带通滤波、零相位滤波 filtfilt
  • scikit-learn:使用 sklearn.cross_decomposition.CCA 做典型相关分析。
  • CSV 标准库:读取 EEG 数据、写入预测结果。
  • pathlib / re / sys:路径解析、文件批处理、命令行参数处理。

数据格式

输入 CSV 文件包含 8 列:

CP3, CPZ, CP4, PO3, POZ, PO4, taskID, stimID

说明:

  • 前 6 列是 EEG 通道数据。
  • taskID 是任务编号,正式数据中为 0-47,一共 48 个任务。
  • stimID 是目标类别。示例数据中是真实标签;正式数据中为 -1,表示待预测答案。

程序不会把正式数据中的 stimID=-1 当作标签参与计算,也不会用它计算正确率。

核心算法

算法主体是 CCA/FBCCA 类型的 SSVEP 识别方法。

整体流程:

EEG数据
  -> 按 taskID 分组
  -> 取 6 个脑电通道
  -> 预处理滤波
  -> 构造每个刺激频率的正余弦谐波参考模板
  -> 计算 EEG 与每个频率模板的 CCA 相关系数
  -> 多频带加权融合
  -> 选择得分最高的频率类别作为预测 stimID

1. 按 taskID 分组

正式数据不能按固定行数简单切片,因为不同任务文件的采样长度不同:

  • S1-S6:每个 taskID 有 750 个采样点,约 3 秒。
  • S7-S12:每个 taskID 有 250 个采样点,约 1 秒。

因此 demo.py 中使用 taskID 分组:

task_data = data[task_ids == task_id]
epoch = task_data[:, :6].transpose()

这样可以保证每个 taskID=0..47 都单独预测一次。

2. 参考信号模板

对于每个刺激频率 f,构造正弦和余弦参考信号:

sin(2πfht), cos(2πfht)

其中:

  • f 是刺激频率。
  • h 是谐波阶数。
  • t 是采样时间点。

完整 4 秒数据使用 5 阶谐波;短窗口正式数据使用 3 阶谐波。

3. 预处理滤波

预处理包含:

  • 50Hz 工频陷波:去除电源干扰。
  • 椭圆带通滤波:保留 SSVEP 相关频段。
  • filtfilt 零相位滤波:避免普通滤波带来的相位偏移。

滤波器组使用 5 个子频带:

8-90 Hz
16-90 Hz
24-90 Hz
32-90 Hz
40-90 Hz

4. FBCCA 多频带融合

程序不是只在一个频带上做 CCA,而是使用 Filter Bank CCA(FBCCA)。

每个子频带都会计算一次 EEG 与模板的 CCA 相关系数 rho,然后进行加权融合:

score = Σ weight(m) * rho(m)^2

权重为:

weight(m) = m^(-1.25) + 0.25

最后选择 score 最大的频率索引作为预测类别。

5. 短窗口自适应策略

正式数据比示例数据短。为了提高短数据的判断准确率,算法对不同长度自动选择配置:

  • 当采样点数等于完整窗口 1000 点时:

    • 使用全部 6 个通道:CP3, CPZ, CP4, PO3, POZ, PO4
    • 使用 5 阶谐波
  • 当采样点数小于 1000 点时:

    • 只使用枕区通道:PO3, POZ, PO4
    • 使用 3 阶谐波

这样做的原因是 SSVEP 主要出现在视觉皮层附近,枕区通道通常信噪比更高。短窗口数据更容易被其他通道噪声干扰,因此短窗口采用枕区通道能提高稳定性。

运行方式

Demo 目录或上级目录运行:

C:/Python311/python.exe e:/Code/BCI-robot/脑机算法竞赛专用U盘资料/Demo/demo.py

默认处理:

数据C1/Task1/S1.csv

也可以指定单个文件:

C:/Python311/python.exe e:/Code/BCI-robot/脑机算法竞赛专用U盘资料/Demo/demo.py S7.csv

也可以指定整个正式数据目录进行批量处理:

C:/Python311/python.exe e:/Code/BCI-robot/脑机算法竞赛专用U盘资料/Demo/demo.py 数据C1

输出文件

单文件运行时:

  • result.csv:最近一次单文件预测结果,容易被覆盖。
  • S*_pred.csv:将原始数据最后一列 stimID 回填为预测值后的完整数据。

批量运行时:

  • result_S1.csvresult_S12.csv:每个正式文件单独对应的 48 个预测值。
  • result_all.csv:12 个正式文件的汇总结果,共 12 × 48 = 576 条。
  • S1_pred.csvS12_pred.csv:每个正式文件回填 stimID 后的完整数据。

整理后的最终文件位于:

FinalResults/

其中:

  • FinalResults/result_all.csv:总预测表。
  • FinalResults/by_file_results/:每个文件单独的结果表。
  • FinalResults/filled_data/:回填答案后的完整 CSV。

验证结果

在带真实标签的示例数据上验证:

完整 1000 点窗口:
D1.csv 48/48
D2.csv 48/48
总计 96/96 = 100%

模拟正式短窗口时:

750 点窗口:
94/96 = 97.92%

250 点窗口:
80/96 = 83.33%

说明:

  • 示例数据有真实标签,因此可以计算准确率。
  • 正式数据的 stimID 全部为 -1,没有真实标签,因此不能计算真实提交准确率。
  • 当前短窗口策略是在示例数据裁剪模拟中验证后采用的,用于提高正式短数据的预测稳定性。

注意事项

  1. 不要用正式数据中的 stimID=-1 计算准确率。
  2. 正式数据必须按 taskID 分组预测,不能按固定 1000 行切片。
  3. result.csv 是临时文件,最终结果应优先使用 FinalResults/ 中整理好的文件。
  4. 如果重新运行 demo.py,部分结果文件可能被覆盖;提交前建议重新检查 FinalResults/README.txtresult_all.csv

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors