☰
CAT12.7安装配置全流程:MATLAB/SPM12环境与批处理避坑
2026/10/27 7:33:53 网站建设 项目流程

简介:CAT12.7版本安装包面向从事脑结构MRI与T1加权影像处理的研究生、科研人员和神经影像工程师,适合需要按既有笔记复现CAT12预处理流程、又难以获取旧版安装文件的用户。压缩包共822个文件、约222.93MB,以312个.m函数脚本和各类MEX预编译文件为核心,搭配.nii、.gii、.annot等影像与皮层分区数据,以及.html说明、.png示意图、.exe辅助程序和.txt配置记录,构成可直接部署的CAT12工具箱及相关模板资源。内容涵盖Schaefer 200/400/600分区、HCP MMP1与a2009s等常用皮层标注,并包含表面处理、拓扑修复、平滑与配准等脚本模块,便于完成分割、配准、皮层重建和结果核查。已有1731人学习下载,对希望稳定复现旧版分析环境、减少版本差异干扰的读者较有参考价值。

1. 源码包不是安装程序:CAT12.7 拿到手先别找 setup

第一次拿到 CAT12.7 安装包的人,十有八九会先在压缩包里翻三遍 setup.exe,翻不到就开始怀疑自己下错了东西。CAT12 属于典型的源码软件,发下来就是几百个 .m 文件加一堆模板和函数目录,没有安装向导,也没有注册表写入,所谓“安装”其实是把目录放对、把路径加对、让 SPM12 认得出它。它跑在 MATLAB 和 SPM12 之上,做脑结构影像的预处理、分割和形态学测量,某实验室一批就是几百个被试,路径错一层、版本差一截,往往不是第一个被试报错,而是跑到第三个才崩,前面的时间全白花。下面按我实际装过的那套顺序来:先把版本钉死,再落目录,然后动参数,最后用一份报告证明它真的活着。

2. 版本对位:MATLAB、SPM12 与 CAT12.7 该谁迁就谁

装 CAT12.7 之前,得先把你手上的三个组件摆到桌面上看一遍:MATLAB 主版本、SPM12 的修订号、CAT12 的目录名。这三者之间的迁就关系是单向的——CAT12.7 迁就 SPM12,SPM12 迁就 MATLAB。搞反了就会遇到那种“装是装上了,一跑就少函数”的玄学问题。

2.1 MATLAB 版本:R2016b 起步,别追最新

SPM12 官方给出的下限很低,MATLAB 7.4 就能启动,但“能启动”和“能跑完 CAT12.7 的完整流程”是两回事。CAT12 是纯 m 文件实现的,里面用了不少较新的语法和函数签名,版本太老会报一堆Undefined function或者Too many input arguments,而报错位置往往在深层函数里,看栈都看不出所以然。

我一般在 R2016b 到 R2020a 这个区间里选,R2018b 和 R2020a 是我装得最多的两个版本。太新的版本(比如刚发布的年度版)不是不能跑,而是 SPM12 的图形界面偶尔会冒出与绘图相关的警告,批处理不受影响,但如果你依赖 GUI 点选参数,这些警告会挡视线。另外提醒一句:SPM12 不依赖任何额外工具箱,不需要 Image Processing Toolbox,也不需要 Statistics Toolbox,别被人忽悠着装一堆。

组件官方下限我实际在用的备注
MATLAB7.4R2018b / R2020a低于 R2016b 容易在深层函数报语法错
SPM12r7487r7771修订号在spm12/Contents.m里能看到
CAT1212.712.7目录名就叫cat12,别带版本后缀
内存8 GB16 GB 以上表面重建阶段峰值最高
磁盘单被试留 1 GB独立数据盘带 surf 输出时单被试可到 800 MB

2.2 SPM12 修订号:r7487 是 CAT12.7 的地板

CAT12.7 的手册里写明了它依赖的 SPM12 最低修订号,低于这条线,CAT12 里调用的某些 SPM 函数签名对不上,表现出来就是初始化阶段直接抛错,或者工具箱菜单压根不出现。很多人的 SPM12 是几年前拷来的老包,目录里没有版本信息,那就打开spm12/Contents.m看头几行的版本号和日期,再和官方发布页对一下。

升级 SPM12 的正确姿势是整目录替换,而不是把新文件覆盖到旧目录上。SPM12 内部有.mex编译文件和tpm模板目录,覆盖安装极易出现新旧混装,最典型的症状是启动时报Invalid MEX-file。我一般把旧的spm12改名成spm12_bak_日期,新包解开后确认spm.m、tpm/、toolbox/三层都在,再开始装 CAT12。

# 查看 SPM12 版本,头几行会有版本号和修订号 head -n 20 /opt/neuro/spm12/Contents.m # 升级时的稳妥做法:旧目录改名保留,新包解到新目录 mv /opt/neuro/spm12 /opt/neuro/spm12_bak_$(date +%Y%m%d) unzip ~/Downloads/spm12_r7771.zip -d /opt/neuro/ ls /opt/neuro/spm12 | head # 应能看到 spm.m、tpm、toolbox 等

head -n 20只读前 20 行,够看清版本;mv保留旧目录是给自己留后悔药,新包跑不起来可以五分钟切回去;解压后ls这一步别省,有些人下载的是嵌套压缩包,解出来是spm12/spm12/,后面所有路径都会错一层。

2.3 路径三条硬规矩:ASCII、无空格、不套娃

这一条是老生常谈,但每年还是有人栽在上面。SPM12 和 CAT12 内部大量用字符串拼接路径,遇到中文目录、空格、括号,某些函数会静默失败——不报错,就是不产出文件,你去翻日志什么都看不到,黑匣子一样。

三条规矩:整个安装路径只用英文字母、数字、下划线和短横线;路径里不能有空格,Program Files这种目录一律避开;解压后只能多一层cat12,如果出现cat12/cat12,说明压缩包多包了一层,得手动把里层提上来。另外不要把工具箱放在同步盘或网络映射盘上,SPM 启动时会扫一遍 toolbox 目录,网络盘延迟会让启动慢到让人怀疑人生,同步盘还会在你跑批处理的时候锁文件。

# 目标结构:spm12/toolbox/cat12 下直接就是 cat_*.m 等文件 cd /opt/neuro/spm12/toolbox unzip ~/Downloads/cat12.7.zip -d . ls -d cat12 && ls cat12 | head -n 10 # 路径合规自检:命中非 ASCII 或空格就提示 echo "$PWD" | grep -qP '[^\x00-\x7F]| ' && echo "路径有问题,换掉" || echo "路径合规"

-d .表示解压到当前目录,也就是 toolbox 下面;ls cat12 | head是确认第一层就是cat12.m、cat_main.m这类文件,而不是又一个cat12目录;grep -qP里的\x00-\x7F排除非 ASCII 字符,管道前的那个空格同时排除空格路径,-q只返回状态不打印,方便写在脚本里做前置检查。

3. 两种装法:塞进 spm12/toolbox 还是独立目录加路径

CAT12 的安装方式本质上只有一种——让 MATLAB 的搜索路径能找到它。区别在于你是把它放进 SPM12 的 toolbox 目录里让 SPM 自动发现,还是放在别处靠 addpath 手工挂上去。两种都能用,适用场景不同。

3.1 方式一:解压进 spm12/toolbox/cat12

这是最省心的方式,也是我默认推荐的。SPM12 启动时会扫描toolbox子目录,发现有spm_cfg_*.m的工具箱就自动注册,在 GUI 的 Toolbox 下拉框里出现一项 CAT12。整个过程不需要你写一行路径代码。

% 启动 MATLAB 后先确认路径,再拉起 SPM spm_dir = '/opt/neuro/spm12'; addpath(spm_dir); % SPM12 主目录 addpath(fullfile(spm_dir, 'toolbox', 'cat12')); % CAT12 显式加入搜索路径 savepath; % 写入 pathdef,下次启动仍有效 spm('Ver') % 应打印 SPM12 spm % 打开 SPM 图形界面

fullfile拼路径比手写斜杠可靠,跨平台不会出错;savepath是把当前路径存进pathdef.m,如果不存,下次开 MATLAB 又得重来一遍;spm('Ver')是启动前的体检,能打印出版本说明 SPM 主体没问题,再开 GUI 才有意义。注意savepath在部分环境下会失败,原因是 MATLAB 安装目录只读,这时它会把pathdef.m写到用户目录下,命令行里会有提示,不影响使用。

装完打开 SPM,Toolbox 下拉框里能看到 CAT12 这一项,点进去是 CAT12 的参数面板,标题栏会标出版本号。如果下拉框里没有,先别急着重装,八成是路径没生效或者解压层级不对,下一章有专门的排查条目。

3.2 方式二:独立目录 + addpath/savepath

有些场景必须用独立目录:比如一个 MATLAB 里要同时挂两个 CAT12 版本做对比,或者 SPM12 装在只读的系统盘上,你没法往 toolbox 里写东西。这时候就把 CAT12 放到数据盘,用genpath加路径。

cat_dir = '/opt/neuro/tools/cat12'; % 独立目录,同样遵守 ASCII 无空格 addpath(genpath(cat_dir)); % genpath 会把所有子目录一起挂上 which cat12 % 应返回 cat_dir 下的 cat12.m

genpath的好处是一次把子目录全带进来,坏处是它会把.git、samples、doc这类无关目录也塞进搜索路径,路径一长,MATLAB 每次函数解析都慢一点。如果追求干净,可以把genpath的结果按行拆开,过滤掉不需要的子目录再加。

真正需要警惕的是版本冲突:两个 CAT12 同时挂在路径上,which只返回排在前面的那个,后面那个的函数仍然可被调用,于是你可能用着 12.7 的主函数,调着旧版的子函数。检查方法是把 path 拆开看有几条含 cat12 的条目。

% 列出所有含 cat12 的路径条目,正常情况下只应该有一条 p = strsplit(path, pathsep); hits = p(contains(p, 'cat12')); disp(hits) % 如果确实有多条,清空后重建(谨慎:会连 SPM 路径一起清掉) % restoredefaultpath; % addpath('/opt/neuro/spm12'); % addpath('/opt/neuro/tools/cat12');

strsplit(path, pathsep)按系统路径分隔符拆成元胞数组,Windows 是分号,Linux 是冒号,用pathsep可以自动适配;contains做子串匹配,比strfind写在循环里清爽。注释里的restoredefaultpath是最后手段,它会把 MATLAB 自带路径之外的条目全清空,清完必须把 SPM12 和 CAT12 重新加上,否则连spm都找不到。

3.3 无授权环境:standalone 与 MATLAB Runtime 的库路径

服务器上没有 MATLAB 授权是常态,尤其是排队集群。这时走 standalone 路线:SPM12 提供编译好的独立版本,靠 MATLAB Runtime(MCR)运行,CAT12 随包提供了对应的 shell 脚本,用来把 CAT12 的批处理交给 standalone 的 SPM 执行。

关键点在于 MCR 版本必须和编译 SPM standalone 时用的 MATLAB 版本严格对应,比如 R2019b 对应 MCR 的 v97 目录,版本错一位就起不来。库路径没配好时的典型报错是error while loading shared libraries: libmwmclmcrrt.so.9.x,看到这个基本就是LD_LIBRARY_PATH的事。

# MCR 三件套路径,版本号按你实际装的改(v97 对应 R2019b) export MCR_ROOT=/opt/mcr/v97 export LD_LIBRARY_PATH=$MCR_ROOT/runtime/glnxa64:$MCR_ROOT/bin/glnxa64:$MCR_ROOT/sys/os/glnxa64:$LD_LIBRARY_PATH cd /opt/neuro/spm12 ./run_spm12.sh $MCR_ROOT script /opt/neuro/jobs/run_cat12_batch.m # 通用入口 # CAT12 随包脚本的用法以 ./cat_standalone.sh --help 的输出为准

runtime/glnxa64放的是 MCR 的核心运行库,bin/glnxa64是工具库,sys/os/glnxa64补系统级依赖,三个都不能少;run_spm12.sh是 SPM12 standalone 的标准入口,第一个参数是 MCR 根目录,第二个参数script表示执行一个 m 脚本。这段建议写进~/.bashrc或者作业提交脚本里,别指望每次登录都记得 export。

4. 参数与批处理:CAT12.7 里我必动的几个开关

装完能启动只是及格线,真正决定成败的是输出目录规划和几个分割参数。CAT12 的默认参数对大多数 3T 结构像都够用,但有几个地方不改,跑到中途翻车的概率明显上升。

4.1 输出目录与磁盘预算

SPM 的批处理里有一个输出根目录,CAT12 会在每个被试的子目录下生成mri/、report/、surf/、label/几个文件夹。很多人图省事把输出目录设成原始数据目录,结果原始 T1 和一堆m*前缀的派生文件混在一起,后面写脚本扫数据时前缀判断写错一次,整批结果就乱套。

我的习惯是原始数据一个盘、输出一个盘、脚本和日志单独一个目录。单个被试的 T1 原始文件大约 10 MB,但完整输出(含皮层表面和厚度)能到 500 到 800 MB,五百个被试就是三四百个 GB,磁盘预算得提前算,别跑到一半No space left on device,那是最难受的一种失败——前面跑完全白费。

提示:输出目录和原始数据目录一定要分开,且都遵守 ASCII 无空格。跑批之前先用df -h看一眼剩余空间,按被试数乘 1 GB 估算。

4.2 APP、LAS 与表面重建:三个影响成败的参数

CAT12 的参数面板项很多,真正需要你判断的其实就三个。

第一个是仿射预处理(APP),它决定图像配准到标准空间的方式。默认的 medium 档对大多数图像够用,遇到原点严重偏斜或者视野缺角的图像,会报仿射配准失败,这时候要么把档位调到 strong 用更多时间换成功率,要么先手工把图像原点设到前连合位置再跑。

第二个是局部自适应分割强度(LAS)。这个参数影响灰白质边界的判定,默认 0.5 在 3T 图像上表现稳定;如果你处理的是 1.5T 或者有明显运动伪影的数据,调到 0.7 到 0.8 会稳一些,代价是耗时增加,而且过度增强会让某些低对比区域被误判。

第三个是表面重建精度。这个参数直接决定surf/目录的体积和运行时间,默认值适合发表级别的形态学分析;如果只是做体积测量、不关心皮层厚度,可以调粗一档,单被试能省下十几分钟。

参数默认我常用的调整什么时候动
APP(仿射预处理)medium原点偏斜时改 strong报仿射配准失败
LAS 强度0.51.5T 数据用 0.7 到 0.8灰白质边界判错
表面重建精度标准只测体积时调粗不需要皮层厚度
并行进程数0(串行)服务器上按核数开被试量大且内存充足
偏场校正强度0.5一般不动线圈不均匀明显时上调

注意:并行进程数不是越大越好。每个进程都吃内存,开到机器内存的七成以上就会开始换页,速度反而比串行慢,还容易在某个被试上 OOM。

4.3 用 spm_jobman 把被试队列串起来

GUI 点选只适合跑一两个被试做验证,真正上量必须用批处理脚本。CAT12 的所有参数都能落到 matlabbatch 结构体里,用spm_jobman执行。下面这份骨架是我反复用过的那套,字段名以你手上批处理编辑器导出的为准,不同小版本的字段层级偶尔会变。

% run_cat12_batch.m —— 放在 /opt/neuro/jobs 下,由 shell 调用 spm_jobman('initcfg'); % 初始化批处理环境,必须先跑这一句 root = '/data/study01'; % 被试根目录,每个被试一个子文件夹 subs = {'sub01','sub02','sub03'}; % 被试列表,实际项目里用 dir 扫出来 for i = 1:numel(subs) t1 = fullfile(root, subs{i}, 'T1.nii'); if ~exist(t1, 'file') fprintf('跳过 %s:找不到 T1\n', subs{i}); continue; % 单个被试缺文件不要中断整批 end matlabbatch = {}; matlabbatch{1}.spm.tools.cat.estwrite.data = {[t1 ',1']}; % ,1 表示取第一帧 matlabbatch{1}.spm.tools.cat.estwrite.nproc = 0; % 0 = 串行 matlabbatch{1}.spm.tools.cat.estwrite.opts.biasstr = 0.5; % 偏场校正强度 matlabbatch{1}.spm.tools.cat.estwrite.extopts.APP = 1070; % 1070 中档,1145 强档 matlabbatch{1}.spm.tools.cat.estwrite.extopts.LASstr = 0.5; % 局部自适应分割强度 matlabbatch{1}.spm.tools.cat.estwrite.output.GM.native = 1; % 输出原生空间灰质 matlabbatch{1}.spm.tools.cat.estwrite.output.warps = [1 0]; % 输出形变场,后续 DARTEL 用 spm_jobman('run', matlabbatch); % 同步执行,出错即中断 end

spm_jobman('initcfg')少写会报批处理未初始化的错;[t1 ',1']里的逗号加数字是 SPM 的卷帧号语法,4D 文件靠它指定第几帧,3D 文件写,1也不会错;nproc = 0表示串行,服务器内存紧张时这是最稳的选择;APP的两个常用值记不住的话可以这么记:数字小的那档快,数字大的那档稳。continue那一句是我踩过坑之后加的——早期脚本遇到缺失文件直接抛错退出,两百个被试跑到第一个坏文件就全停了。

外层用一个 shell 脚本包起来,好处是日志能落到文件、进程能丢到后台、断了还能重跑。

#!/usr/bin/env bash # run_cat12.sh —— 放在项目根目录,nohup 后台执行 set -euo pipefail LOG_DIR=/data/study01/logs mkdir -p "$LOG_DIR" matlab -nodisplay -nosplash -r "run('/opt/neuro/jobs/run_cat12_batch.m'); exit" \ > "$LOG_DIR/cat12_$(date +%Y%m%d_%H%M).log" 2>&1

-nodisplay关掉图形界面,服务器上省资源也避免 X11 相关报错;-nosplash跳过启动画面;-r后面那句必须带exit,否则 MATLAB 跑完不退出,进程一直挂着,你还以为在算。日志文件名带时间戳,同一批跑多次不会互相覆盖,重跑对比时很有用。set -euo pipefail让脚本在任一命令失败时立刻停下,别让错误静默传下去。

5. 避坑排查:五条装完才暴露的报错

下面这五条基本覆盖了我在不同机器上遇到的全部情况,按出现频率从高到低排。每条的写法都是现象、原因、解决,照着定位比盲目重装快得多。

5.1 SPM 的 Toolbox 下拉里找不到 CAT12

现象:MATLAB 里spm能正常启动,Toolbox 下拉框只有 SPM 自带那几项,没有 CAT12。

原因:九成是解压层级错了,spm12/toolbox/cat12/cat12/这种双层目录 SPM 扫不到;剩下一成是 CAT12 被放在了 toolbox 之外,你以为自己加过路径,其实没savepath,重开 MATLAB 就丢了。

解决:进spm12/toolbox看一眼,第一层必须是cat12.m;如果是双层,把里层mv上来再删掉空壳。路径方式装的,重开 MATLAB 后执行which cat12,返回空就说明路径没存住,补一句savepath再试。

5.2 报 Undefined function 'cat_vol_...' 或函数被旧版顶掉

现象:点开 CAT12 面板时正常,一按运行就报某个cat_vol_开头的函数未定义,或者参数校验时报函数签名不匹配。

原因:路径上同时存在两份 CAT12,或者 SPM12 的修订号低于 CAT12.7 要求的下限,CAT12 调用的 SPM 内部函数在老版本里不存在。

解决:先用strsplit(path, pathsep)查出所有含 cat12 的条目,多于一条就清理掉旧的;再看spm12/Contents.m的修订号,低于 r7487 就整目录替换 SPM12,别搞覆盖安装。

5.3 批处理在第二个被试报 Affine registration failed

现象:第一个被试顺利跑完,第二个被试在仿射预处理阶段报错退出,日志里只有一句配准失败,看不出具体原因。

原因:那个被试的图像原点严重偏离,或者视野被裁掉了小脑/额极,默认中档的仿射配准找不到稳定解。这种情况在跨中心合并的数据里特别常见。

解决:先把这例图像单独拉出来在查看器里确认原点位置,能手工设原点就设;批量处理时把 APP 调到 strong 档,并打开“忽略错误继续”的选项,让个别失败被试跳过而不是中断整批,事后单独补跑。

5.4 Out of memory:不是加内存条就能解决

现象:跑到表面重建阶段 MATLAB 报Out of memory,但系统free -h看着还有余量。

原因:多数情况不是物理内存不够,而是并行进程开太多,每个进程各占一份峰值内存,加起来超了;少数情况是 MATLAB 的 Java 堆没调,GUI 开着跑大图时尤其明显。

解决:nproc调回 0 串行跑,或者按“物理内存除以单进程峰值”算出安全的进程数;服务器上统一用-nodisplay跑批,不启 GUI。真到了内存瓶颈,优先减少并行数而不是加内存条。

5.5 Linux 下 standalone 起不来:libmwmclmcrrt.so 找不到

现象:执行 SPM standalone 脚本立刻退出,报error while loading shared libraries: libmwmclmcrrt.so.9.x: cannot open shared object file。

原因:LD_LIBRARY_PATH没包含 MCR 的运行库目录,或者装的 MCR 版本和编译 SPM standalone 时的版本对不上。

解决:把 MCR 的三个库目录加进LD_LIBRARY_PATH并写进环境变量文件;确认 MCR 版本号与 SPM standalone 的编译版本一致,不一致就换 MCR,别硬凑。改完在同一个 shell 里ldd一下可执行文件,看依赖是否全部解析成功。

6. 验证跑通:拿 SPM12 自带的 T1 跑一份 cat_*.html 报告

装完之后我不看菜单、不看版本号,直接跑一个真实被试,能产出完整报告才算装好。SPM12 的canonical目录里自带一份标准 T1,single_subj_T1.nii,拿来当验证样本最合适——它不占空间、结构干净,跑一遍大约几分钟,比拿真实数据试错划算得多。

% verify_cat12.m —— 最小验证脚本,跑通说明安装没问题 spm_jobman('initcfg'); t1 = fullfile(spm('Dir'), 'canonical', 'single_subj_T1.nii'); % SPM12 自带样本 matlabbatch = {}; matlabbatch{1}.spm.tools.cat.estwrite.data = {[t1 ',1']}; matlabbatch{1}.spm.tools.cat.estwrite.nproc = 0; matlabbatch{1}.spm.tools.cat.estwrite.output.GM.native = 1; spm_jobman('run', matlabbatch);

spm('Dir')返回 SPM12 的安装根目录,用它拼样本路径可以避免写死绝对路径,换机器也能用;这份脚本只开灰质输出,把表面重建关掉(这里没写相关字段就是走默认,想更快可以显式关),目的是验证主流程而不是压测性能。

跑完之后按下面这张表逐项核对,四项全过,安装就算落地了。

检查项位置期望结果
主函数解析MATLAB 里which cat12返回 CAT12 目录下的cat12.m
版本号CAT12 面板标题或版本文件显示 12.7
分割产物输出目录mri/出现m*前缀的灰质、白质、脑脊液文件
质量报告输出目录report/生成cat_*.html,打开能看到分割图像和体积统计

那个 HTML 报告是我最看重的一项,它把分割 overlay 直接画在原始图上,灰白质边界对不对、有没有明显的过分割,一眼就能看出来。打开报告如果图像是空白的,别怀疑报告坏了,多半是输出目录权限不对,文件写了 0 字节。

从那以后我每次装完 CAT12,都会先拿这份自带样本跑一遍,四项对上再去动项目数据。这个习惯救过我好几次——有一次是路径里有空格导致报告写不出来,还有一次是新旧版本混装,主流程能跑但报告里的体积统计明显异常,靠这一遍最小验证提前发现,总比在三百个被试跑完之后才发现强。

这套 CAT12.7 安装包我已经按上面说的目录结构整理好了,解开就能直接往 toolbox 里放,需要的话从资源入口自取。希望帮到你。

本文还有配套的精品资源,点击获取

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

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

立即咨询