直接说结论:fMRI原始数据分割这件事,听起来像是一个处理步骤,实际上它是整个预处理流程里最容易出错、也最影响后续结果质量的一环。我见过太多人跑完一整套SPM流程,最后发现分割结果一团糟,灰质概率图惨不忍睹,回头排查才发现是slice timing的slice order填反了,或者是segment时affine regularization选错了模板。这种坑,纯靠自己摸索真的很费时间,所以我把这几年处理fMRI原始数据的笔记整理出来,希望能帮你少走弯路。
这篇笔记面向的是刚开始接触fMRI数据分析、或者已经在跑预处理但被分割环节卡住的朋友。我会把“分割”这件事拆成两个层面来讲:一是时间维度上的分割(slice timing,时间层校正),二是空间维度上的分割(组织分割,tissue segmentation),这两个操作虽然名字都带“分割”,但原理、目的、操作方式完全不同。我还会结合SPM12和FSL里最常用的做法,把参数设置、操作顺序、常见报错一次性讲透。
1. 先搞清楚“分割”到底指什么
1.1 时间维度上的分割
fMRI扫描是一层一层扫的,一个TR内要采几十层图像。磁共振机器不是瞬间把整个脑壳同时拍下来的,它需要按照特定顺序一层一层地采集。常见的采集方式有顺序采集(sequential,从第1层到第N层)和隔层采集(interleaved,先扫奇数层再扫偶数层)。这就意味着,同一个TR里,第1层和第30层的采集时间差了整整一个TR的几分之几,而这个时间差会让BOLD信号产生相位偏移。
时间层校正(slice timing)要做的就是:选一个参考时刻,把所有层面通过插值对齐到那个时间点,让数据在时间上“看起来”是同时采集的。这一步处理不好,后面算出来的激活体素位置会偏移,时间序列的频谱也会被污染。
我刚开始做的时候,一直不理解为什么slice timing要放在realign前面做。后来想明白了:头动校正这一步,会把不同时刻采集的图像在空间上重新排列,图像的强度值是通过插值重采样的。如果先做realign再做slice timing,等于先对空间做了插值、再对时间做插值,两次插值叠加,信号失真会更明显。所以SPM官方流程默认是slice timing → realign → coregister → segment,这个顺序有它的道理,别随便改。
1.2 空间维度上的分割
空间分割指的是把大脑图像按组织类型分成灰质(GM)、白质(WM)、脑脊液(CSF)。这一步在SPM里对应的是Segment模块,在FSL里对应的是FAST。空间分割的核心原理是:基于组织概率图先验,再结合图像本身的强度分布,用混合高斯模型估算每个体素属于灰质、白质、脑脊液的概率。
空间分割的目的通常有两个。第一个是VBM分析,你要比较两组人的灰质体积差异,就得先把灰质概率图提取出来做配准和统计。第二个是作为fMRI预处理的一环,分割得到的白质和脑脊液概率图,可以用来提取噪音信号(比如aCompCor方法),用于回归掉呼吸、心跳等生理噪音。所以分割的质量直接影响后续统计分析的敏感性。
空间分割里有个容易忽略的细节:这一步虽然叫“分割”,但它不只是分灰白质,它还会同时估计配准参数和偏置场(bias field correction)。也就是说,SPM的Segment实际上是同时在做分割+配准+偏置场校正三件事。理解了这一点,你在看分割输出文件的时候就不会困惑,为什么除了c1、c2、c3(分割概率图)之外,还有y_.nii(变形场)和m.nii(偏置场校正后的图像)。
1.3 为什么原始数据阶段就要处理分割
“原始数据分割”这个说法,我理解有两层含义。一是字面上的,直接从原始数据开始做slice timing,这是预处理的第一步。二是数据处理习惯上的,很多人喜欢在拿到原始数据后,先做一个初步的质量检查(QC),看看每个通道的信号是否正常、有没有大范围的头动伪影,然后再决定分割参数怎么设。
不管从哪层含义理解,有一点是共通的:分割的参数一旦定错,后面所有步骤都会被带偏。slice timing的slice order错了,你可以在realign阶段发现时间序列变得很奇怪,但那时你没法确定是slice timing的问题还是头动的问题。segment的affine regularization选错了,DARTEL配准出来的脑形态图就会有系统性的形变偏差。所以,分割这一步值得多花点时间,把每个参数的含义和你的数据采集方式对齐。
2. Slice Timing实操:从参数计算到参数设置
2.1 三组关键参数必须算清楚
用SPM12做slice timing,界面看起来很简单,但参数填错很常见。需要你准确填定的有:number of slices(总层数)、TR(重复时间,单位秒)、TA(TR减去有效采集时间后的间隔)、slice order(层面采集顺序)、reference slice(参考层)。这几个参数看起来很基础,但它们每个都能毁掉你的数据。
number of slices一般等于你的扫描序列参数里Slice number的值,国产3T机器上常见的是32层、40层、48层。TR也很直观,就是序列参数里的Repetition Time,注意单位是秒,不是毫秒。最容易出问题的是TA,SPM的帮助文档里写的是TA = TR - (TR / number of slices),很多教程直接告诉你用这个公式,但没说清楚这个公式的适用条件。
TA的完整含义是:在每一个TR内,机器实际采集完所有层之后,到下一个TR开始采集之前,那段“空窗期”的时长。对于2D多层采集序列来说,假设TR=2s,采了40层,每层采集时间是0.05s,那么实际采集时间是40×0.05=2s,TA=0。但现实是,2D序列的TR通常是总采集时间的1.0到1.5倍左右,也就是说会有一定的“空闲时间”,TA的计算标准公式是TA = TR - (TR / nslices),这个式子来源于SPM文档,它假设每层采集的时间是相等的。
不过我在实际处理中发现,很多序列的TA并不是这么算的。最稳妥的办法,是直接看扫描序列的源参数,有些厂商的序列参数里会直接给出“Slab Time”或者“Acquisition Time”,如果没有,才退回去用公式估算。还有一个快速验证技巧:做完slice timing之后,把任意一个体素的时间序列画出来,如果时间序列的频谱明显出现高于任务频率的锯齿状波动,多半是slice timing的参数没填对。
2.2 slice order怎么确认
slice order这个东西,是很多新手栽跟头的地方。你需要在你的扫描参数里找到层面采集的顺序,顺序采集就填[1:1:nslices],隔层采集一般有两种可能:先奇数层后偶数层,或者从第2层开始先偶数后奇数。
以32层为例,如果是隔层采集、从第1层开始先奇数,那么slice order填:1,3,5,...,31,2,4,6,...,32。如果是隔层采集、从第2层开始先偶数,那么填:2,4,6,...,32,1,3,5,...,31。这些信息一般会在设备厂商的序列说明里标注,英文一般叫“Interleaved (odd-first)”或“Interleaved (even-first)”。
一个我踩过坑的细节:有些序列是隔层采2遍(multi-band/多频带采集),它实际的层面采集顺序跟普通隔层不太一样,slicetiming工具不一定支持,需要用专门的工具。如果你用的是多频带序列,建议先问问设备工程师,拿到这组序列的slice acquisition group参数,别硬套普通序列的规则。另外,如果序列参数实在查不到,可以做一个简单实验:快速扫一组静息态数据,用FSL的slicetimer工具跑一遍不同的--order选项,对比校正后图像的时间序列平滑度,也能反推出采集顺序。
2.3 FSL方案和SPM方案怎么选
SPM的slice timing操作图形化、直观,但如果你想批量处理很多人,用SPM的batch脚本会更高效。FSL的slicetimer是命令行工具,命令很简单:slicetimer -i 输入文件 -o 输出文件 --tcustom=文件 或 --ocustom=文件。
FSL里需要你给定的是--repeat(TR)、--tcustom(每层采集时间文件)或者--ocustom(slice order文件),此外还有一个--direction参数,用于指定层面的采集方向。FSL的这个--direction参数经常被人忽略,它表示的是层面编号沿着哪个空间轴递增。默认是z轴(自上而下),但有些序列是沿着y轴采集的,如果没有指定,校正等于白做。
SPM和FSL的选择,我的建议很直接:如果你后续要用SPM做DARTEL或VBM分析,那就全程SPM,保持处理管线统一;如果你后续要用FSL的FEAT做first-level分析,那就用FSL的slicetimer。混用不是不行,但会引入额外的格式转换和排序烦恼。
3. Segment组织分割:SPM操作流程与参数详解
3.1 SPM12 Segment模块的功能拆解
打开SPM12,点Segment按钮,会弹出一个界面,你只需要选入T1像(严格来说应该是T1加权结构像,如果是原始fMRI数据没有T1,那需要先配准到结构像上)。Segment的核心里面有好几个Tab,最常用到的就是Data和Tissue,其他选项一般保持默认。
在Data这个栏里,你需要指定的是Image。如果在run fMRI预处理流程时,你用的是T1结构像做分割,那Image就是coregister之后的T1图像。这里有个容易混淆的点:分割用的图像,应该是高分辨率的结构像(T1),而不是低分辨率的EPI功能像。EPI的功能像虽然也能分割,但空间分辨率不够,组织边界不清晰,分割出来的概率图质量会明显偏差。
Tissue栏里默认有6个组织类:灰质(c1)、白质(c2)、脑脊液(c3)、骨骼(c4)、软组织(c5)、背景(c6)。如果只是做fMRI预处理需要灰白质分割,前三个就够了,后面的可以不管。每个组织类下面有Native Tissue、DARTEL等选项,默认的Native是Saved,会把灰质、白质、脑脊液的概率图各存一份c*.nii,这个就够了。
还有一个容易被忽略的选项是Warped Tissue(配准到标准空间的概率图)。如果你做VBM分析,需要把灰度图配准到MNI空间,那么Warped Tissue要选“Save”。如果你只是做fMRI预处理,一般不需要保存warped segmentation,省点硬盘空间。
3.2 Bias Regularization和Affine Regularization怎么填
Segment里最让人摸不着头脑的就是Bias Regularization和Affine Regularization。这两个参数直接决定偏置场校正的平滑程度和配准的初始变换。
Bias Regularization,全称是“偏置场正则化”,它控制的是估计偏置场时的平滑约束强度。默认值Lightly regularised (0.0001)大多数情况下都够用。如果你的图像有明显的强度不均(比如T1像靠近皮层的地方很亮、深部很暗),可以适当调到Medium regularised (0.001)。但要注意,调高正则化只会让偏置场估计更平滑,对于严重的强度不均,先试试SPM里另一个单独的Bias Correction工具,别指望靠Segment一个模块解决。
Affine Regularization,这个参数选择比较重要。它控制的是分割时跟模板做仿射配准的强度,SPM默认是“ICBM Space Template - European Brains”。这里有一个坑:如果你处理的是亚洲人群的数据,用“Average sized template”会更合适,因为平均脑大小与目标人群更匹配。我见过很多人全程用默认值,结果配准到MNI空间后图像里脑子的整体缩放比例不对,体积统计偏差明显。
我个人的经验是:处理亚洲人群的数据,直接把Affine Regularization改成“Average sized template”,其他保持默认,然后跑完分割后把c1(灰质)图跟T1像叠加起来看一眼,如果灰质边界贴合得很好,说明参数没问题;如果灰质图大范围覆盖到白质区,说明分割对配准的依赖太大,可以尝试调整。
3.3 FSL FAST:命令行分割的操作要点
如果你用FSL做分割,对应的工具是FAST(FMRIB's Automated Segmentation Tool)。一条典型命令是:
fast -t 1 -n 3 -H 0.1 -I 4 -o output_basename T1_brain.nii.gz
这里的参数含义:-t 1表示输入是T1图像种类;-n 3表示分成3个组织类(灰质、白质、CSF);-H 0.1是空间平滑度;-I 4是最大迭代次数。
FAST比较关键的一点是:它要求输入图像必须先做脑提取(skull-stripping),也就是要先跑过BET或类似工具,把非脑组织去掉。这一点跟SPM不一样,SPM的Segment不需要先做脑提取,它自己会处理。所以你用FAST时,管线的顺序是:BET脑提取 → FAST分割。
FAST跑完之后会生成几个文件:_seg.nii.gz(分割标签图)、_pve_0.nii.gz、_pve_1.nii.gz、_pve_2.nii.gz(对应的灰质、白质、CSF概率图)、*_mixparam.txt(混合高斯参数)等。其中pve开头的文件就是概率图,对应SPM的c1、c2、c3,可以用于后续的噪音回归。
3.4 DARTEL与分割结果的进阶应用
如果你做VBM分析,分割完之后还要做DARTEL配准。DARTEL的核心思想是:把每个人的灰质、白质概率图一起用来估计一个非线性变形场,然后通过迭代精修得到高精度的空间配准结果。
在SPM12里,DARTEL流程是这样的:Segment → DARTEL (create templates) → DARTEL (existing templates) → Normalise to MNI。在Segment之后,你需要在Tissue的DARTEL选项里选择“Imported”,这样会生成rc1*.nii和rc2*.nii,也就是从原始空间重采样到DARTEL输入空间的组织概率图。接着DARTEL会逐步生成模板,这个过程会花不少时间,但对结果的精确度来说值得。
DARTEL做完之后,每人的灰质图已经被扭曲到标准空间,可以用modulation选项来把体积形变考虑进去,再做Smoothing,最后才能做统计。整个DARTEL流程比较长,但每一步都是为最终统计准确性服务的。
4. 分割前的数据准备与格式转换
4.1 DICOM到NIfTI:带着全局操作的转换
fMRI原始数据通常以DICOM格式存盘,而SPM、FSL这些工具只能处理NIfTI格式,所以你第一步要做的就是把DICOM转成NIfTI。推荐用dcm2niix,这是目前公认最好用的转换工具,它可以从一串DICOM文件里正确推断出三维体积的排列顺序,自动生成4D文件(如果是功能像的话),并且把大部分关键采集参数写进NIfTI的头文件里,方便后面读取。
dcm2niix的典型命令是:
dcm2niix -f "%p_%s" -o 输出目录 输入DICOM目录
-f参数控制输出文件的命名格式,%p是序列名称,%s是序列号。我常用的命名方式是%p_%s_%d(序列名_序列号_实例号),这样方便我区分同一被试的不同序列。转换后,记得检查一下生成的.json文件,里面会记录SliceTiming、PhaseEncodingDirection等参数,这些参数跟slice timing的设置直接相关。
还有一个dcm2niix的细节:在转换4D功能像时,默认会生成一个.nii.gz和一个.json文件。如果开了-b选项(BIDS格式),输出文件名会变成sub-xxx_task-xxx_run-xxx_T1w.nii.gz这种风格。如果你打算把数据整理成BIDS格式,建议转的时候直接加-b参数,省得后面再改。
4.2 头动校正和分割的先后逻辑
预处理流程里,头动校正(realign)在slice timing之后,在segment之前。这个顺序是有讲究的。slice timing需要图像层面之间的时间信息保持原始采集状态,如果先做realign,层面之间的时间关系会被空间插值打乱,slice timing就失去了意义。所以标准逻辑是:先做slice timing,再做realign,再做coregister(把功能像配准到结构像),最后做segment。
realign的输出是*_unwarped.nii或经过重排的*r*.nii。跑完realign后,/tmp文件夹里会生成rp*.txt文件(头动参数,6列),这个文件在后续做运动回归时会被用到。如果你发现某个被试的头动位移超过3mm,或者旋转超过3度,这个被试的fMRI数据后面做统计时很可能需要排除或特殊处理,分割参数也要重新检查。
4.3 批处理脚本:一个人处理一百个被试的经验
处理大量被试时,手动在SPM图形界面里一个个点,效率太低了。推荐的做法是写一个MATLAB批处理脚本,把slice timing、realign、coregister、segment放在一起跑。SPM12的batch模块可以记录你每一步的操作,然后在MATLAB里直接运行。
一个基础模板长这样:
matlabbatch{1}.spm.temporal.st.scans = {功能像列表}; matlabbatch{1}.spm.temporal.st.nslices = 40; matlabbatch{1}.spm.temporal.st.tr = 2; matlabbatch{1}.spm.temporal.st.ta = 2 - (2/40); matlabbatch{1}.spm.temporal.st.so = [1:2:39, 2:2:40]; matlabbatch{1}.spm.temporal.st.refslice = 20; matlabbatch{1}.spm.temporal.st.prefix = 'a';这里的prefix='a'表示输出的文件名会加一个a前缀,a开头的文件就是slice timing校正后的数据。然后realign的matlabbatch是下一段,coregister再一段,segment一段。整个脚本一次能处理一个被试的所有数据,只要把你的路径统一管理好。
批处理的时候有个经验:先选两个被试手动跑一遍全流程,确认每个步骤的输出文件名和期望一致,再放开跑全组。不然全组100个被试跑到一半发现某个参数填错了,只能全部重来。
5. 常见问题与排查技巧实录
5.1 一张速查表帮你定位90%的问题
我把这几年遇到的分割相关报错和异常汇总成了一张表,排查的时候先看这张表,能省很多时间。
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| slice timing后时间序列频谱有锯齿 | slice order填错,或者TA计算不对 | 核对扫描序列的SliceTiming参数,重新计算TA |
| 分割后灰质概率图几乎全为0 | 输入图像不是T1结构像,而是功能像 | 换用T1结构像,重新检查coregister结果 |
| c1图大范围覆盖白质区 | Affine Regularization选错模板 | 改成Average sized template或No regularization |
| Segment报错“Cannot find file” | 路径中包含中文或特殊字符 | 把路径改成全英文数字,去掉空格和中文 |
| 分割后图像方向颠倒 | NIfTI方向头字段有问题 | 用fslreorient2std或MRIcron重新设置方向 |
| DARTEL创建模板时崩溃 | rc1/rc2图像命名不匹配,或输入图像维度过大 | 确认rc1/rc2文件正确生成,检查图像是否经过重采样调整分辨率 |
| FAST结果里白质中间出现空洞 | 脑提取不彻底,残留的脑膜/血管像素干扰 | 重新跑BET,适当下调阈值 |
5.2 我踩过的slice timing坑
有一次处理一批数据,TR=2秒,40层,TA按公式算出来是1.95秒(2 - 2/40 = 2 - 0.05 = 1.95?注意单位:TR=2s,nslices=40,TR/nslices=0.05s,TA=1.95s),结果跑完slice timing,时间序列的功率谱出现了明显的规则性尖峰。我一开始以为是头动问题,看rp文件最大位移0.5mm,正常得很。后来仔细一查,发现这个扫描序列虽然是40层,但实际是multi-band因子为4的多频带采集,真正的slice acquisition group不是40个独立时刻,而是10个时刻内完成4层同时激发。这种情况下用普通slice timing的模型去插值,自然会出现频谱污染。
排查了很久,最终确认问题的根源是TA的计算方式不适用多频带采集。多频带序列的slice timing本质上跟单频带不一样,它的层面采集时间是“成组”的,SPM默认的slice timing模型不能直接套用。解决方案是:要么用设备商自带的预处理工具,要么用AFNI的3dTshift做时间层校正(它支持更灵活的时间参数输入),要么在SPM里把每一组当作一个“层面”来处理(但这样空间分辨率会受损)。
5.3 分割结果怎么快速检查
分割完不等于万事大吉,我每次都会花几分钟检查分割质量。最直接的检查方式:在SPM里用Check Reg功能,把分割结果(c1、c2、c3)叠加到原始T1图上。正常的灰质概率图应该是薄薄一圈贴在大脑皮层表面,白质概率图是深部大片区域,脑脊液是脑室和沟回处的信号。
如果灰质概率图大面积出现在脑室外或者看起来像散落的碎片,多半是偏置场校正或配准出了问题。如果灰质和白质比例严重失衡(比如灰质体积占了80%以上),可能是分割时把脑膜或血管分进了灰质,可以尝试调高Bias Regularization或者先做颅骨剥离。
另外一个批量质检技巧:把每个被试的c1图体积或weighted global signal提取出来,画个散点图。如果某个被试的体积异常偏离全组均值,那这个被试的分割结果很可能有问题。
5.4 解锁VBM分析前必须做的数据质量关卡
分割完成后,别急着做统计。在产出最终的灰质密度/体积图之前,还有几个关卡必须过:
检查coregister结果:EPI图像有没有和T1错位。如果功能像和结构像没对齐,用EPI分割得到的组织概率图就是废的。用Check Reg把alignment显示出来,旋转角度看看,任何错位都要排查。
检查配准到MNI之后图像是否过度形变:跑完DARTEL或Normalise后,看每个被试的warped图像在MNI坐标下跟标准模板是否重合。如果某个被试的脑形态变成畸形,要么是分割时出了问题,要么是该被试脑部有病变。
处理异质性数据:如果你手上有不同中心、不同磁场强度的扫描数据,别直接扔到一起分割。最好先按扫描参数分组,分别做质量检查,再统一到同一预处理管线。不同场强下T1对比度差异,会影响组织分割的边界判定。
6. 关于分割参数,我最后想说的话
处理fMRI数据这几年,我最大的感受是:分割这个环节,参数设置远没有你想象的那么“自动”。SPM的Segment做得再智能,它也只是一个工具,真正决定输出质量的,是你对数据本身的了解程度。
拿到一批新数据,我会花15分钟做三件事:一,看扫描序列的完整参数表,确认TR、TE、翻转角、层面数、采集顺序;二,随机抽一个被试,用MRIcron把DICOM或NIfTI打开,逐层翻一遍,确认没有明显的大面积伪影;三,跑一遍slice timing和segment后,把结果图截出来人工看一眼。这三件事做完,数据能不能直接用,我心里基本就有数了。
最后再分享一个小技巧:做分割之前,在Linux终端或MATLAB里先把每个被试的文件权限和路径统一检查一遍。我之前就因为在Windows上同步数据时文件后缀变成了大写,导致批处理脚本在一个被试手上卡住,后面所有被试全部白跑。数据管理这件事上偷懒,后面大概率会加倍还回去的。