脑电波控制设备:基于典型相关分析(CCA)的脑机接口频率精准解码方法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、CCA的用途
  • 二、频率求解思路
  • 三、输入数据结构
  • 四、判断方法
  • 五、matlab实践
    • 1.数据集获取及处理
    • 2.matlab代码
    • 3.运行及结果
  • 六、参考文献


前言

        在脑机接口(BCI)领域,有SSVEP方向,中文叫做稳态视觉诱发电位,当人观看闪烁的视觉刺激(比如闪烁的灯光或图像)时,大脑会在与刺激频率一致的频率上,产生电位波动。这段脑电波是一种稳定且容易检测的脑电信号。通过确定ssvep波的频率,可以准确地判断用户正专注于哪个视觉刺激目标,帮助BCI系统识别用户意图,从而控制相应的设备或应用。例如,用户可以通过注视不同频率的方块或图标来控制计算机光标、游戏角色、轮椅等设备。还可以通过确定频率成分,对脑部健康状况进行初步筛查或监控,进而识别一些可能的脑部异常活动。
在这里插入图片描述


一、CCA的用途

        过去广泛使用的频率检测方法是PSDA,基于功率谱密度的分析,例如傅里叶变换,小波变换等。CCA(典型相关分析,Canonical Correlation Analysis) 是一种多变量统计分析方法,用于研究两组变量之间的相关性。在SSVEP-BCI(稳态视觉诱发电位-脑机接口)系统中,通常利用CCA来提取信号的频率特征并解码用户的意图。CCA的核心目标是通过求解典型相关系数来寻找两个信号集之间的关联性。

The most widely used frequency detection method in SSVEP-based BCIs is power spectral density based analysis。(PSDA)在基于SSVEP的脑机接口中,最广泛使用的频率检测方法是基于功率谱密度的分析。


二、频率求解思路

        使用CCA,需要输入两个变量, X X X Y Y Y X X X 是采集到的数据, Y Y Y 是用已知的标准正余弦信号做为模板进行预设的数据。CCA旨在找到一对变换矩阵 A A A B B B ,使得变换后的两个信号集之间的相关性最大化。相关性就体现在相关系数 p p p 的求解上:
max ρ = cov ( A X , B Y ) cov ( A X , A X ) ⋅ cov ( B Y , B Y ) \text{max} \quad \rho = \frac{ \text{cov}(A X, B Y) }{ \sqrt{ \text{cov}(A X, A X) \cdot \text{cov}(B Y, B Y) } } maxρ=cov(AX,AX)cov(BY,BY) cov(AX,BY)
        在得到的所有系数中,找到最大的系数。最大系数对应的频率,与SSVEP波频率相关性最大,就代表了SSVEP波的频率就是这个值。


三、输入数据结构

        使用数据结构说明如下描述,看图辅助文字理解。输入 x x x 的行数为通道数8, x x x 是采集到的数据。输入 y y y 行数为使用的谐波数6, y y y 是标准正余弦信号。 x x x y y y 两者的列数为时间t。
        输入的 x x x y y y 数据结构如下图
x是采集到的数据,y是标准正余弦信号
         y y y 是标准正余弦信号,是下图这样的形式
y是标准正余弦信号

CCA works on two sets of variables. In our method, variables in one set are the signals, x(t),recorded from several channels within a local region and the second set is from stimulus signals.
CCA处理两组变量。在我们的方法中,一组变量x(t)是从局部区域内的几个通道记录的信号,第二组变量来自刺激信号。


四、判断方法

        相关系数最大时的频率,就是我们要找的频率。而相关系数 p = λ 2 p=λ² p=λ2 ,这个关系由CCA理论推导得到。篇幅所限这里只记结论,后续会发另一篇文章,零基础理论学习CCA典型相关分析,内有详细推导,包教包会。这里想求出 p p p ,只要找到对应特征值,开根号就好了。

找到最大的p对应的频率

Suppose there are K stimulus frequencies f1,f2,…fk and that the analyzed signal has been acquired from N channels within an Ls window. Our strategy for recognition is as follows. where p(f) is the CCA coefficient of xLN and y.
假设有K个刺激频率 f1,f2,…fk,并且所分析的信号是在一个长度为Ls的窗口内从N个通道中获取的。我们的识别策略如下。刺激频率fs满足 p(f) 是 xLN 和 y 的 CCA 系数。

In this approach, EEG signals from multiple channels are used to calculate the CCA coefficients with all stimulus frequencies in the system. The frequency with the largest coefficient is the one of SSVEP.
在该方法中,使用EEG信号来自多个通道,来计算系统中所有刺激频率的CCA系数。具有最大系数的频率是SSVEP的频率。


五、matlab实践

1.数据集获取及处理

        使用清华大学脑机接口研究组的公开数据集,链接 https://bci.med.tsinghua.edu.cn/
        此处下载使用Wearable SSVEP BCI Dataset的S1~S10。

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f9f7fc600ec849d2821660cb31156572.png

        该数据集刺激信息如下图,一共12个频率。
在这里插入图片描述
        根据An Open Dataset for Wearable SSVEP-BasedBrain-ComputerInterfaces,这篇文章对该数据集的描述。

        该数据集包括102个MATLAB MAT文件,对应于102个受试者的脑电图数据。所有文件都是根据参与者的索引命名的(即S001.mat、S102.mat)。每个文件都包含一个名为“data”的5-D矩阵,维度为[8,710,2,10,12],并存储为双精度浮点值。五个维度分别表示“通道标号”、“时间点”、“电极标号”、”块标号“和”目标标号“。每个矩阵对应240个历元(12个目标×10个块×2个电极),每个历元由未经任何处理的8个通道的原始脑电图数据组成,长度为2.84s(2.84s×250=710个时间点)
        根据连续EEG数据的事件通道中记录的刺激起始点,可以提取数据历元。每个数据历元的长度为2.84s,包括刺激开始前0.5s、视觉反应延迟0.14s、刺激后2s和刺激后0.2s。为了降低存储和计算成本,所有数据都被下采样到250 Hz。

        这里因为采样频率为250hz,所以一秒可以采集250个点,所以2.84s采集 2.84 s × 250 = 710 2.84s×250=710 2.84s×250=710 点。 或者这样计算,采样点数 N N N,采样时间 T T T,采样间隔 T s Ts Ts ,采样频率 f s fs fs ,
N = T / T s N = T / Ts N=T/Ts
T s = 1 / f s Ts = 1 / fs Ts=1/fs
所以
N = 2.84 / ( 1 / 250 ) = 2.84 x 250 = 710 点 N= 2.84 / (1/250) = 2.84 x 250 = 710点 N=2.84/(1/250)=2.84x250=710
        我们只使用采集的数据验证下CCA,不需要像文章里,对不同的通道/电极做对比评测。所以只需要拿第二个维度上,710个采集数据点使用即可。在这里用的 x x x 是data_1只取8个通道刺激后2秒的数据,即2~2.84秒,只取最后0.84s的数据,对应210个点。所以 y y y 在公式中的T要用到210个值。 T / S = 210 / 250 = 0.84 T/S = 210/250 = 0.84 T/S=210/250=0.84 这也刚好说明是对应时间长度的。

2.matlab代码

        测试代码test_CCA.m如下,根据文中信息,数据 x x x 要使用8个通道的数据。对 y y y 的构建,只使用6个谐波。测试代码配合CCA算法,两个文件配合使用。这里仅读取S001.mat。
         test_CCA.m :

%*******  test_CCA.m  **********%
% 加载.mat文件
load('S001.mat');% 获取data变量部分数据
data_1 = data(:,501:710,1,1,1);  % 8x210% t  6x84
t = 1:210;  % 定义要用来循环的fre的值
fre_values = [9.25, 11.25, 13.25, 9.75, 11.75, 13.75, 10.25, 12.25, 14.25, 10.75, 12.75, 14.75]; % 可以根据需要添加更多值%% cca
x = data_1'; % 210x8
A_list = zeros([6, 12]); % 初始化存储 A 的多维数组
B_list = zeros([8, 12]); % 初始化存储 B 的多维数组
C1_list = zeros(1, length(fre_values)); % 初始化存储 C1 的单元数组% 循环通过fre_1的值并生成相应的data_2矩阵
for i = 1:length(fre_values)fre = fre_values(i);data_2 = [sin(2*pi*fre*t/250);cos(2*pi*fre*t/250);sin(4*pi*fre*t/250);cos(4*pi*fre*t/250);sin(6*pi*fre*t/250);cos(6*pi*fre*t/250)];y = data_2'; % 210x6[A, B, C1] = CCA(x, y);C1_list(i) = C1;A_list(:, i) = A;B_list(:, i) = B;
end
[max_value, index] = max(C1_list);
P = sqrt(max_value);  % 相关系数p等于λ,这里特征值是λ的平方,后面开根号
fprintf('最大相关系数 p = %.5f\n', P); % %.5f 表示保留5位小数
A = A_list(:, index)
B = B_list(:, index)
fprintf('当前注视的图像频率为 %.2f Hz\n', fre_values(index)); % %.2f 表示保留两位小数

        CCA算法, CCA.m :

%********  CCA.m  *********%
function [A,B,C1]=CCA(X,Y)
%CCA canonical correlation analysis
% [A,B]=cca(X,Y)
dimx=size(X,2); dimy=size(Y,2);  %列数(变量数)
Sall = cov([X Y]);  %cov求协方差矩阵。原阵X大小为M*N,则cov(X)大小为N*N的矩阵
dim=min(dimx,dimy);
Sxx=Sall(1:dim,1:dim);
Syy=Sall(dim+1:end,dim+1:end);
Sxy=Sall(1:dim,dim+1:end);
Syx=Sall(dim+1:end,1:dim);iSxx=inv(Sxx);  %矩阵求逆
iSyy=inv(Syy);M1 = iSxx*Sxy*iSyy*Syx;
M2 = iSyy*Syx*iSxx*Sxy;% 使用 SVD 分解
[U1, S1, V1] = svd(M1);  % M1 的奇异值分解
[U2, S2, V2] = svd(M2);  % M2 的奇异值分解% 手动单位化 U1 和 U2:使得每列(奇异向量)的模长为 1
for i = 1:size(U1, 2)U1(:, i) = U1(:, i) / sqrt(U1(:, i)' * U1(:, i));  % 每列单位化
endfor i = 1:size(U2, 2)U2(:, i) = U2(:, i) / sqrt(U2(:, i)' * U2(:, i));  % 每列单位化
end% 手动归一化 S1 和 S2,使得最大奇异值为 1
S1 = S1 / max(diag(S1));  % 将 S1 的最大奇异值归一化为 1
S2 = S2 / max(diag(S2));  % 将 S2 的最大奇异值归一化为 1% A ...... 选择最大奇异值对应的奇异向量
[maxVals1, colIndex1] = max(diag(S1));  % 找到最大奇异值所在的列
A = U1(:, colIndex1);  % 选择对应的奇异向量
C1 = maxVals1;  % 最大奇异值
A = A * diag(1 ./ sqrt(A' * Sxx * A));  % 归一化,注意矩阵的大小匹配% B ...... 选择最大奇异值对应的奇异向量
[maxVals2, colIndex2] = max(diag(S2));  % 找到最大奇异值所在的列
B = U2(:, colIndex2);  % 选择对应的奇异向量
B = B * diag(1 ./ sqrt(B' * Syy * B));  % 归一化,注意矩阵的大小匹配

3.运行及结果

        将测试代码test_CCA.m和CCA.m文件与数据S001.mat放到同一目录下,方便读取。
在这里插入图片描述
        运行结果为9.25hz,相关系数和 A , B A,B A,B 具体值,matlab版本不同会有轻微差异。
在这里插入图片描述

六、参考文献

CCA学习:
Z. Lin, C. Zhang, W. Wu and X. Gao, “Frequency Recognition Based on Canonical Correlation Analysis for SSVEP-Based BCIs,” in IEEE Transactions on Biomedical Engineering, vol. 53, no. 12, pp. 2610-2614, Dec. 2006, doi: 10.1109/TBME.2006.886577.

数据集来源:
Zhu F, Jiang L, Dong G, Gao X, Wang Y. An Open Dataset for Wearable SSVEP-Based Brain-Computer Interfaces. Sensors (Basel). 2021 Feb 10;21(4):1256. doi: 10.3390/s21041256.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31130.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

fiddler+雷电模拟器(安卓9)+https配置

一、fiddler配置 1、开启https代理 2、根证书安装:导出证书系统安装 二、模拟器设置 1、设置网络桥接模式 【点击安装】提示安装成功后保存即可 2、开启root(开启adb远程调试) 3、开启磁盘写入 4、设置WLAN代理 5、证书安装:物…

跨越时空的对话:图灵与GPT-4聊AI的前世今生

(背景:虚拟咖啡厅,图灵身着1950年代西装,端着一杯热茶,GPT-4以全息投影形态坐在对面) 图灵(喝了口茶):“听说你能写诗?我当年在布莱切利园破解Enigma时&…

双击PPT文件界面灰色不可用,需要再次打开该PPT文件才能正常打开

双击PPT文件界面灰色不可用,需要再次打开该PPT文件才能正常打开 1. 软件环境⚙️2. 问题描述🔍3. 解决方法🐡解决步骤 4. 结果预览🤔 1. 软件环境⚙️ Windows10 或 Windows11 专业版64位,安装MotionGo软件&#xff08…

【时间序列聚类】Feature-driven Time Series Clustering(特征驱动的时间序列聚类)

文章目录 1.文章介绍2.问题背景3.拟解决的问题4.主要贡献5.提出的方法5.1模型pipeline5.2特征抽取和选择5.3图渲染和社区检测5.4共现矩阵的构建5.5对共现矩阵进行聚类 6.实验6.1模型设置6.2实验结果6.3消融实验 7.结论8.个人观点9.Reference 1.文章介绍 论文出处:ED…

tomcat负载均衡配置

这里拿Nginx和之前做的Tomcat 多实例来实现tomcat负载均衡 1.准备多实例与nginx tomcat单机多实例部署-CSDN博客 2.配置nginx做负载均衡 upstream tomcat{ server 192.168.60.11:8081; server 192.168.60.11:8082; server 192.168.60.11:8083; } ser…

SQLAlchemy系列教程:如何执行原生SQL

Python中的数据库交互提供了高级API。但是,有时您可能需要执行原始SQL以提高效率或利用数据库特定的特性。本指南介绍在SQLAlchemy框架内执行原始SQL。 在SQLAlchemy中执行原生SQL SQLAlchemy虽然以其对象-关系映射(ORM)功能而闻名&#xff…

19.HarmonyOS Next CustomSlider组件基础教程(一)

温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! 1. 组件介绍 Slider(滑动选择器)是HarmonyOS中常用的交互组件,用于在给定的数值范围内进行连续值的选择。本教…

管中窥豹数字预失真(DPD)

管中窥豹数字预失真(DPD) 数字预失真在通信领域发挥了巨大的作用,对提高功放效率、改善误码率起了不可忽略的作用,广泛运用与通信、雷达等各种领域。但是对于普通用户,它显得及其高深神秘。今天就用这个短文&#xff…

MCP极简入门:超快速上手运行简单的MCP服务和MCP客户端

MCP是什么? 首先我们快速过一下MCP的基本概念,接着我们会通过一个简单的天气服务的教程,来上手学会使用MCP服务和在主机运行服务。本文根据官方教程改编。 1. MCP的基本概念 MCP(Model Context Protocol,模型上下文…

DeepSeek进阶应用(一):结合Mermaid绘图(流程图、时序图、类图、状态图、甘特图、饼图)

🌟前言: 在软件开发、项目管理和系统设计等领域,图表是表达复杂信息的有效工具。随着AI助手如DeepSeek的普及,我们现在可以更轻松地创建各种专业图表。 名人说:博观而约取,厚积而薄发。——苏轼《稼说送张琥》 创作者&…

海康线扫相机平场矫正教程

0、平场矫正前的准备确认 1、白纸准备 确保视野中有一张平整且无折痕的白纸,使其完全铺满相机的整个视野。 2、行高设置 将行高参数设定为 2048。 3、灰度值控制 相机端图像的灰度值应维持在 120 - 180 这个区间内。同时,最亮像素点与最暗像素点的灰度…

数智读书笔记系列015 探索思维黑箱:《心智社会:从细胞到人工智能,人类思维的优雅解读》读书笔记

引言 《The Society of Mind》(《心智社会》)的作者马文・明斯基(Marvin Minsky),是人工智能领域的先驱和奠基者之一 ,1969 年获得图灵奖,被广泛认为是对人工智能领域影响最大的科学家之一。他…

游戏引擎学习第148天

回顾并规划今天的工作 没有使用引擎,也没有任何库支持,只有我们自己,编写游戏的所有代码,不仅仅是小小的部分,而是从头到尾。现在,我们正处于一个我一直想做的任务中,虽然一切都需要按部就班&a…

bug-Ant中a-select的placeholder不生效(绑定默认值为undefined)

1.问题 Ant中使用a-select下拉框时,placeholder设置输入框显示默认值提示,vue2ant null与undefined在js中明确的区别: null:一个值被定义,定义为“空值” undefined:根本不存在定义 2.解决 2.1 a-select使…

DeepSeek教我写词典爬虫获取单词的音标和拼写

Python在爬虫领域展现出了卓越的功能性,不仅能够高效地抓取目标数据,还能便捷地将数据存储至本地。在众多Python爬虫应用中,词典数据的爬取尤为常见。接下来,我们将以dict.cn为例,详细演示如何编写一个用于爬取词典数据…

springboot-自定义注解

1.注解的概念 注解是一种能被添加到java代码中的【元数据,类、方法、变量、参数和包】都可以用注解来修饰。用来定义一个类、属性或一些方法,以便程序能被捕译处理。 相当于一个说明文件,告诉应用程序某个被注解的类或属性是什么&#xff0c…

低代码开发直聘管理系统

低代码 DeepSeek 组合的方式开发直聘管理系统,兼职是开挂的存在。整个管理后台系统 小程序端接口的输出,只花了两个星期不到。 一、技术栈 后端:SpringBoot mybatis MySQL Redis 前端:Vue elementui 二、整体效果 三、表结…

【面试】Kafka

Kafka 1、为什么要使用 kafka2、Kafka 的架构是怎么样的3、什么是 Kafka 的重平衡机制4、Kafka 几种选举过程5、Kafka 高水位了解过吗6、Kafka 如何保证消息不丢失7、Kafka 如何保证消息不重复消费8、Kafka 为什么这么快 1、为什么要使用 kafka 1. 解耦:在一个复杂…

文件操作详解(万字长文)

C语言文件操作 一、为什么使用文件?二、文件分类三、文件的打开和关闭四、文件的顺序读写4.1fputc4.2fgetc4.3fputs4.4fgets4.5 fprintf4.6 fscanf4.7 fwrite4.8 fread 五、文件的随机读写5.1 fseek5.2 ftell和rewind六、文件读取结束的判定七、文件缓冲区 一、为什…

突破极限!蓝耘通义万相2.1引爆AI多模态新纪元——性能与应用全方位革新

云边有个稻草人-CSDN博客 目录 一、 引言 二、 蓝耘通义万相2.1版本概述 三、 蓝耘通义万相2.1的核心技术改进 【多模态数据处理】 【语音识别与文本转化】 【自然语言处理(NLP)改进】 【跨平台兼容性】 四、 蓝耘注册 部署流程—新手也能轻松…