☰
fNIRS光极可视化与通道坐标计算实战:基于NIRS-SPM的完整流程
2026/10/2 9:43:03 网站建设 项目流程

最近在整理fNIRS数据分析流程时,发现很多刚接触近红外成像的朋友,最容易卡住的地方反而不是后续的GLM统计,而是最前面的“我的光极到底戴得对不对”、“通道坐标怎么算”这类基础问题。市面上讲fNIRS预处理和统计的教程不少,但专门讲光极可视化、通道坐标计算的系统性内容确实不多。这篇博文是我打算写的一个系列的第一篇,就用我自己跑通的流程,把NIRS-SPM这套基于MATLAB的工具箱从加载数据、可视化光极到计算通道坐标的全过程拆开讲一遍。

我会把每一步的原理、操作、以及我当时踩过的坑都写清楚,尽量做到你拿着这篇内容,对着自己的数据也能一步步跑出来。这篇内容主要面向刚接触fNIRS数据处理、对MATLAB有一定基础但还没完全上手NIRS-SPM的研究生和科研助理,当然,如果你用的是商用设备(比如日立、岛津、NIRx),想搞清楚设备自带的坐标文件到底怎么转换成标准空间坐标,这篇也能帮上忙。

1. 内容整体设计与思路拆解

1.1 为什么要做光极可视化和通道坐标计算

先说个业务场景。你做完一次fNIRS实验,拿到了原始数据,但这时候你手上只有一堆光强信号,你根本不知道这堆信号是从大脑哪个位置采来的。如果你用的是商用设备,厂商软件会给你一个二维的通道排布图,告诉你通道大概在哪个脑区,但这里有个问题:二维排布图并不能真实反映探头在三维头皮上的空间位置。

人的个体头型差异很大,同样按照国际10-20系统放置的探头,在不同被试头上的实际物理位置会有几毫米到一厘米的偏差。如果你要做组水平分析,需要把所有被试的通道坐标统一到一个标准空间(比如MNI空间),或者要在结果报告里展示通道对应的大脑皮层区域,这时候就必须知道每个通道的三维坐标。

光极可视化的价值就在这:它能让你在三维空间里直观看到发射光极、接收光极和通道的空间关系,检查通道排布是否符合实验设计预期,有没有通道因为间距不合适导致信号质量差。而通道坐标计算,则是后续做空间配准、把fNIRS结果和fMRI结果进行联合分析的基础。

1.2 为什么选择NIRS-SPM而不是其他工具

fNIRS数据处理工具目前主流的有这么几个:Homer(基于MATLAB,侧重预处理)、NIRS-SPM(基于MATLAB,侧重统计建模和空间分析)、带你入门的商用软件(日立UCL、NIRx NIRStar等),还有基于Python的MNE-NIRS。

我选择NIRS-SPM做这个系列的开篇,有几个实际考量。

NIRS-SPM是伦敦大学学院Wellcome Trust Centre的Ye博士团队开发的,学术背书扎实,参考文献体系完整,你在论文方法部分写“使用NIRS-SPM进行通道坐标计算和空间配准”,审稿人不会质疑。第二,这个工具是开源免费的,而且对硬件设备没有强绑定,日立、岛津、NIRx的数据基本都能导入处理,这对于实验室里有多台设备的研究者来说非常方便。第三,NIRS-SPM内置了蒙特卡洛光子传输模拟(Monte Carlo photon transport simulation)的接口,能基于Colin27标准脑模板生成光在头皮、颅骨、脑脊液、灰质中的传输路径,从而估计每个通道实际探测的脑区,这是很多商用软件做不到的。最后一点也实在,NIRS-SPM的图形界面操作比较直观,不需要写大量脚本就能完成基本的光极可视化和坐标计算,对新手友好。

1.3 整体技术路线梳理

这篇博文的实操流程,我按照自己跑通的顺序来安排:

第一,准备好MATLAB环境和NIRS-SPM工具箱,加载被试的原始数据或光极排布文件。第二步,利用NIRS-SPM的通道空间定位模块,定义光极坐标。第三步,运行可视化模块,在三维脑模型上渲染光极和通道位置。第四步,导出通道坐标,进行MNI空间标准化。最后,把整个流程串起来,讨论常见问题和排查技巧。

这里有个概念需要先讲清楚:光极坐标和通道坐标是两个不同的东西。光极坐标是指每个发射光极和接收光极在头皮表面的三维坐标,而通道坐标是指一个发射-接收光极对之间的测量位置坐标。在NIRS-SPM里,通道位置通常取发射和接收光极的中点,或者根据蒙特卡洛模拟的光子传输路径加权得到更精确的位置。

2. 核心细节解析与实操要点

2.1 NIRS-SPM工具包的安装与配置

NIRS-SPM的安装不算复杂,但有一些细节需要注意。

你首先需要从官方渠道下载NIRS-SPM工具包。下载完成后解压,把整个文件夹放到MATLAB的toolbox目录下,或者放到你习惯存放工具箱的任意目录。关键一步是在MATLAB里设置路径:打开Set Path,选择Add with Subfolders,把你解压的NIRS-SPM文件夹添加进去,保存。这一步千万不要省,漏了子文件夹,后续很多函数会报Undefined function错误。

接下来验证安装是否成功。在MATLAB命令行输入:

which nirs_spm.m

如果返回了完整的文件路径,说明安装成功。如果提示找不到,检查路径是否添加完整,或者是否因为MATLAB版本问题导致函数兼容性异常。

我用的MATLAB版本是R2021a,NIRS-SPM目前对R2018以后的版本兼容性都不错,但如果你用的是老版本(比如R2015以前),部分图形界面函数可能会报错,建议升级MATLAB版本。

2.2 理解fNIRS光极排布与通道构成

在进行可视化之前,你得先明白你的光极排布数据是怎么来的、长什么样。

最常见的fNIRS光极排布方式是源-探测(source-detector)配对。一个发射光极和一个接收光极组成一对,它们之间的区域就是一个测量通道。通道间距(即源探测距离)直接影响测量深度,一般30mm左右的光极间距能探测到大脑皮层表面约15mm深处的信号。太短了只能测到头皮血流,太长了信号衰减严重,信噪比降低。

光极排布文件在NIRS-SPM中有一套自己的格式要求。它本质上是一个文本文件,每一行记录一个光极的三维坐标(x, y, z,单位mm)以及光极类型。举个例子,一个包含4个发射光极和4个接收光极的排布文件,内容大致是这样的:

# 光极类型 x坐标(mm) y坐标(mm) z坐标(mm) S -89.0 -20.0 0.0 D -89.0 -20.0 0.0 ...

当然,实际文件里的坐标是从设备定位系统(比如三维数字化仪)或者按10-20系统换算得到的。不同的商用设备导出的格式可能不同,比如日立设备导出的通道信息里包含的是光极编号和通道编号,你需要先转换成坐标文件格式。

2.3 理解坐标系统:从设备空间到标准空间

这里要插一个比较关键的概念,因为后面计算通道坐标时会反复用到。

fNIRS设备记录的光极坐标,最初是在设备空间里的,也就是说,坐标值是以设备自己的参考框架(一般是设备的中心点或者某个固定参考点)为原点建立的。而我们在论文里报告结果时,通常使用的是标准空间,也就是MNI152模板空间或者Talairach空间。

从设备空间到标准空间的转换,需要一个中间步骤:先把设备空间坐标配准到被试的解剖像空间(如果有MRI的话),或者配准到一个标准头皮模板(如果没有个体MRI的话)。NIRS-SPM的做法是让你在光极文件中指定参考点,比如鼻根(Nasion)、左耳前点(Left ear)、右耳前点(Right ear),然后利用这些参考点做空间变换。

这就解释了为什么你在定义光极坐标时,除了光极本身的三维坐标,还必须提供至少三个参考点的坐标。没有这些参考点,NIRS-SPM就无法完成空间配准,后面的MNI空间标准化也就无从谈起。

2.4 配置光极文件:一步步建立你的坐标体系

现在进入实战环节。我以自己的一个实际实验数据为例(光极排布为4×4,即8个发射光极和8个接收光极,共20个通道),展示如何一步步配置光极文件。

打开NIRS-SPM图形界面,输入以下命令:

nirs_spm

这时会弹出一个主界面。在主界面中找到与通道空间定位相关的模块,通常叫Channel或者Spatial相关按钮。点击后,界面会要求你选择数据文件或光极排布文件。

NIRS-SPM支持的输入格式有两种:一种是.nirs数据文件(包含光极位置信息的原始数据),另一种是单独的.txt光极排布文件。如果你手头的数据是.nirs格式,那么光极信息可能已经嵌入在数据里了,直接加载即可。如果你拿到的只是商用设备导出的文本文件(比如日立的.csv通道信息),你就需要自己构建光极排布文件。

构建光极排布文件时,有一个很容易犯的错误:光极编号和通道编号搞混。一个通道必然包含一个源和一个探测,但一个源可以对应多个探测,一个探测也可以对应多个源。4×4排布中,一个源可能和相邻的三个探测组成三个通道。你必须在文件中把通道定义和光极位置一一对应,否则后续计算出来的通道坐标会完全错乱。

我的做法是,先画一个光极排布示意图,标注每个光极的编号,然后列出通道表(哪些源-探测对组成一个通道),最后再创建坐标文件。顺序一定不能乱。

3. 实操过程与核心环节实现

3.1 数据准备:光极坐标文件与通道排布文件

我建议你准备两个独立文件:一个是光极坐标文件,定义了每个光极的三维坐标和类型;另一个是通道排布文件,定义了哪些光极对组合成通道。分开存放的好处是,当你要修改排布方案时,不需要改动坐标文件,逻辑更清晰。

光极坐标文件格式(我习惯用一个简单清晰的格式):

Nasion 0.00 89.00 0.00 LPA -79.00 0.00 0.00 RPA 79.00 0.00 0.00 S1 -30.00 60.00 15.00 D1 -10.00 65.00 20.00 ...

前三行是参考点(鼻根、左右耳前点),后面每一行是一个光极。注意参考点的坐标不是随便写的,你需要使用三维定位设备或者根据10-20系统坐标换算得到。如果没有个体头模数据,也可以使用标准头皮模板上的参考点坐标。

通道排布文件格式可以是简单的文本:

S1-D1 S1-D2 S2-D1 ...

这里S1-D1表示第一个发射光极和第一个接收光极组成一个通道。

3.2 在NIRS-SPM中加载并可视化光极

数据准备好之后,打开NIRS-SPM的通道可视化模块。具体操作是:在主界面选择Channel相关选项,然后在弹出的对话框中选择你要加载的数据文件或光极坐标文件。

如果加载成功,NIRS-SPM会利用内置的Colin27标准脑模板,在三维空间中渲染出头皮表面,并把光极位置以球体形式显示出来。发射光极和接收光极会用不同颜色区分(通常是红色表示源,蓝色表示探测),通道则以连接线或者信道的方式显示。

我第一次跑通可视化时,直观感受就是“原来我的通道是真的戴歪了”。因为之前在设备软件上看二维排布图觉得挺对称,到三维空间里一看,有个别通道因为光极间距不均匀,明显偏离了设计位置。这其实就是做光极可视化的直接价值之一——质量检查。

如果你想在可视化时同时查看通道编号,NIRS-SPM也支持在通道位置标记序号,这样你后续做ROI分析时,可以很直观地从图上找到对应通道。

3.3 蒙特卡洛模拟与通道坐标位置计算

光极可视化只是第一步,真正重要的是计算通道坐标。NIRS-SPM提供了基于蒙特卡洛模拟的通道定位功能。

蒙特卡洛模拟的原理可以简单这么理解:光子在头皮表面进入组织后,会在不同组织层中随机散射和吸收,最终有一部分光子会到达接收光极。通过模拟大量光子的随机行走路径,就能估计出光子在组织中的传输概率分布,从而确定这个通道实际“探测”到的大脑区域。

在NIRS-SPM中运行蒙特卡洛模拟,需要调用MontoCarlo相关的函数。一个基本用法是:先定义通道数据(源和探测的空间坐标、光极间距、光波长等参数),然后调用模拟函数,得到每个通道的光子传输概率分布图。基于这个概率分布,可以计算每个通道的质心坐标,这个质心坐标比简单的“中点坐标”更精确地反映通道的实际探测位置。

模拟得到的通道坐标会保存在一个输出结构里,你可以导出查看。坐标值的单位是mm,所在的坐标系是标准MNI空间(基于Colin27模板)。这意味着,你后续可以直接把这些通道坐标和一个标准解剖模板对应起来,查看每个通道对应的Broadmann分区或者脑网络节点。

3.4 通道坐标的导出与后续应用

当你完成蒙特卡洛模拟并得到通道坐标后,下一步是导出数据。

NIRS-SPM允许你以文本文件形式导出通道坐标,格式包含通道编号、MNI坐标值、以及对应的脑区标签(如果有配准的话)。导出后,你可以用其他软件(比如xjView、MRIcron)进一步查看通道在标准脑上的位置,或者用这些坐标做后续的ROI分析。

这里有一个我实际用过的技巧:把导出的通道坐标和功能连接矩阵结合起来做网络可视化。比如你计算完各通道间的功能连接之后,可以把通道坐标作为网络节点的空间位置,用BrainNet Viewer这类工具画一个三维脑网络图。审稿人对这种图通常印象会比较好,因为它很直观地展示了大脑区域之间的连接模式。

3.5 完整流程代码演示

把上面的流程用代码固化下来,方便你后续批量处理。以下是我常用的一个脚本模板:

% 加载NIRS-SPM工具箱 addpath(genpath('D:\Tools\NIRS_SPM')); % 定义数据参数 data_file = 'D:\Experiment\Subject01.nirs'; % 加载数据 nirs_data = nirs_load(data_file); % 提取光极位置信息 optode_positions = nirs_data.optodes; % 设置参考点(Nasion, LPA, RPA) ref_points = optode_positions(1:3, :); % 创建通道排布 channel_pairs = [ 1, 2; % S1-D1 1, 3; % S1-D2 2, 3; % S2-D1 ... ]; % 运行蒙特卡洛模拟计算通道坐标 channel_coords = nirs_spm_montocarlo(optode_positions, channel_pairs); % 可视化 nirs_spm_visualize(channel_coords); % 导出坐标 writematrix(channel_coords, 'channel_coordinates.txt', 'Delimiter', 'tab');

这个脚本里的函数名我做了简化处理,实际调用时你需要在NIRS-SPM的函数清单里找到对应的准确命名。核心逻辑是清楚的:加载数据,提取光极位置,设置参考点,定义通道,计算坐标,可视化,导出结果。你把这段逻辑理解透了,配合NIRS-SPM自带的demo脚本,自己改编成适合自己数据结构的代码不会太难。

4. 常见问题与排查技巧实录

4.1 数据加载失败或路径错误

这是最常遇到的问题,而且往往不是因为NIRS-SPM本身出错,而是文件路径配置问题。

一个典型场景是:你要加载的.nirs文件和光极坐标文件不在当前MATLAB工作目录下,而你在代码里写的是相对路径。解决方案很简单,在脚本开头加上cd命令切换到数据所在目录,或者使用绝对路径。

还有一种情况是文件名包含了中文或特殊字符。MATLAB在某些版本下对中文路径支持不够好,会报无法读取文件。我的建议是,所有实验数据相关路径都使用纯英文命名,一个字母都不要用中文,省心。

4.2 蒙特卡洛模拟速度慢或内存不足

蒙特卡洛模拟的计算量确实不小,需要模拟成千上万个光子的随机游走过程。如果你发现运行时间过长,可以调整光子数量参数,比如从默认的100000个光子减少到50000个,计算精度会稍微下降,但速度能提升一倍。

如果报内存不足错误,检查一下你的输出结构保存在哪里。NIRS-SPM有时候会把每个通道的概率分布图都保存在内存里,通道数量多的话确实会吃内存。解决方案是及时清理不需要的中间变量,或者把输出结果直接写入磁盘而不是保留在工作区。

4.3 光极坐标文件格式不符

这是我自己踩过的坑。不同版本的NIRS-SPM对光极文件的要求略微不同,早期的版本用空格分隔字段,后来的版本可能要求用制表符分隔。建议先仔细看工具箱自带的示例文件,对照格式修改自己的文件。

有一个细节特别容易出错:坐标文件的标题行。有些版本要求第一行不能是标题行,必须直接是数据。我习惯先不写标题行,数据文件直接上数值,这样兼容性最好。

4.4 通道坐标结果出现异常值

如果你计算出来的通道坐标明显偏离合理范围(比如坐标超过±200mm),大概率是参考点设置出了问题。参考点坐标和光极坐标必须处于同一个坐标系,不能参考点用的是标准空间坐标,而光极位置用的是设备空间坐标,这样配准必然出错。

另外一个可能原因是光极间距设置不合理。蒙特卡洛模拟需要知道源探测距离,如果距离设置过近(比如小于10mm),模拟结果会很奇怪。通常30mm是一个标准参考值。

4.5 常见问题速查表

问题现象可能原因排查与解决方案
函数未定义路径未设置或子文件夹未添加检查addpath,确认已添加子文件夹
光极可视化无显示坐标文件为空或格式错误用文本编辑器打开文件,检查行列数据完整性
蒙特卡洛模拟卡死光子数量过大或内存不足减少模拟光子数,释放内存空间
通道坐标偏差大参考点配准错误或坐标系混乱统一坐标系,核对参考点数值
导出的坐标文件打不开格式与目标软件不兼容用MATLAB重新导出CSV格式或空格分隔格式

5. 写在最后:一个实验设计的建议

如果你刚开始规划一个fNIRS实验,我把自己的经验浓缩成一句话:光极坐标的采集,一定不要等到实验做完再补。

我见过不少课题组的流程是:先用设备跑完所有被试,数据处理阶段才想起需要光极坐标,然后翻实验记录本找当时的排布图,或者靠记忆重新摆放光极位置去测量。这种做法误差极大,因为每次戴设备的位置都有偏差。正确做法是,每个被试戴好设备后、开始实验前,用三维定位仪记录光极位置和三个参考点位置,存成一个单独的文件,被试编号命名,随原始数据一起归档。这样做的好处是,后面做通道坐标计算时,每个被试都有自己的真实坐标,组水平分析时还能考察个体差异对结果的影响。

另外提醒一句,很多商用设备的定位文件格式是封闭的,你需要用设备厂商的软件导出成通用格式,再转换成NIRS-SPM需要的格式。这一步可能需要一些编程工作,但弄清楚之后,你会发现后续整个分析流程都会顺畅很多。

这个系列接下来我会继续写fNIRS预处理、GLM统计分析、以及通道级别到皮层级别的映射,感兴趣的话可以关注后续更新。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询