主要流程:Realignment、Slice Timing Correction、Coregistration、Segmentation、Normalization
程式碼地址:https://github.com/zhoushusheng/fMRI_preprocessing/blob/main/stupid_batch_nii_third_formal_compilable.m
引數設定參考:
1:上海外國網課https://www.bilibili.com/video/BV1ye4y1m72P/spm_id_from=333.880.my_history.page.click&vd_source=9b75cfd2936571e6bc329144e79be03e
2:Andy's brain book:https://andysbrainbook.readthedocs.io/en/latest/SPM/SPM_Short_Course/SPM_04_Preprocessing.html
%----------------------------------------------------------------------- % Job saved on 02-Sep-2019 18:21:16 by cfg_util (rev $Rev: 6942 $) % spm SPM - SPM12 (7219) % cfg_basicio BasicIO - Unknown %----------------------------------------------------------------------- %% % 這個m檔案用來執行spm的matlabbatch % 該檔案中的檔案位置是基於linux系統的,如果是windows系統需要修改/為\ clear % spm_path = '~\spm12'; %設定spm12的位置(這裡填的是安裝=spm12的絕對位置) 我這裡已經安裝好了 % addpath(spm_path); spm('defaults', 'fmri'); spm_jobman('initcfg'); %% subjectsdir = {'B:\fMRI\preprocess_for_batch\CN\'};% 這裡是data資料夾的絕對位置 subjects = {'sbj01','sbj02','sbj03','sbj04','sbj05','sbj06','sbj07','sbj08','sbj09','sbj10','sbj11','sbj12','sbj13','sbj14','sbj15','sbj16','sbj17','sbj18','sbj19','sbj20','sbj21','sbj22','sbj23','sbj24','sbj25'... ,'sbj26','sbj27','sbj28','sbj29','sbj30','sbj31','sbj32','sbj33','sbj34','sbj35','sbj36'}; % 單個或多個被試的資料夾 funcdir = fullfile('fMRI'); % 第一個Session的資料夾(由於preprocessing.mat中只新增了一個Session,所以這裡也只使用一個Session。) % F = fullfile(FOLDERNAME1, FOLDERNAME2, ..., FILENAME) builds a full % file specification F from the folders and file name specified. Input % arguments FOLDERNAME1, FOLDERNAME2, etc. and FILENAME can be strings, % character vectors, or cell arrays of character vectors. Non-scalar % strings and cell arrays of character vectors must all be the same size. % FULLFILE collapses inner repeated file separators unless they appear at % the beginning of the full file specification. FULLFILE also collapses % relative folders indicated by the dot symbol, unless they appear at % the end of the full file specification. Relative folders indicated % by the double-dot symbol are not collapsed. % % funcdir2 = fullfile('Session2'); % 第二個Session的資料夾 anatdir = fullfile('MRI'); % 結構像的資料夾 %% % 設定基本的引數,在這裡設定方便後期修改 % head = spm_vol(sessionfiles{1}); % dimension = head.dim; % slice_number = dimension(1,3); % slice_number = 35; % TR = 3; % TA = TR-TR\slice_number; % slice_order = [1:2:slice_number 2:2:slice_number]; % refslice1 = 35; % voxel_size= [3.75 3.75 4]; % smoothing_kernel = [6 6 6]; %% %每一個被試都建立一個工作流程 nsubj = length(subjects); % 被試的數量 jobs = cell(nsubj,1); % job的數量,每個被試一個job nrun=1; % session的數量 %ntimepoint=190; %刪除了前面的10個時間點後剩餘的時間點 %% for csubj = 24:36 subjdir = {spm_select('CPath',subjects{csubj}, subjectsdir)};%Cpath 的c = canonical % 結構像資料夾 adir = spm_select('CPath', anatdir, subjdir); %選擇當前被試(csubj)的結構像資料夾 anatfile = strcat(spm_select('FPList', adir, '\\*.nii'),',1'); %在這個資料夾中.nii結尾的檔案,即結構像檔案 % As above, but return files with full paths (i.e. prefixes 'direc' to each) %如果沒有結構像檔案就報錯 if isequal(anatfile, '') warning(sprintf('No anat file found for %s', ... subjects{csubj})) return end % Session1資料夾 fdir = {spm_select('CPath', funcdir, subjdir)}; %選擇當前被試(csubj)的Session1資料夾 ffiles = spm_select('List', fdir, '\\*.nii'); %選擇這個資料夾中所有.nii結尾的檔案,即Session1的所有原始功能像檔案 %如果沒有功能像檔案就報錯 nimage = size(ffiles,1); if nimage == 0 warning(sprintf('No functional file found for %s', subjects{csubj})) return end cffiles = cellstr(ffiles); ntimepoint = length(cffiles); funcfiles = cell(1, nrun); sessionfiles = cell(nrun,ntimepoint); for i = 1:nrun for j = 1:ntimepoint sessionfiles{i,j}=strcat(fdir{1},'\',cffiles{j}); % 在這裡在每一個功能像檔案的絕對路徑後面新增,1 end funcfiles{1,i} = {sessionfiles{i,:}}'; % 如果有多個Sessions,funcfiles中就會有多個sessionfiles end clear matlabbatch length(cffiles); head = spm_vol(sessionfiles{1}); dimension = head.dim; descrip = head.descrip; slice_number = dimension(1,3); descrip={descrip};%char To cell TR = regexp(descrip,'(?<=TR=)\d+|(?<=TR=)\d+\.\d+','match','once'); TR = str2double(TR); TR = TR / 1000; %如果沒有查到TR就報錯 if isequal(TR, '') warning(sprintf('No TR parameter found for %s', ... subjects{csubj})) return end TA = TR-TR/slice_number; %這個就得自己看了 % slice_order = [1:2:slice_number 2:2:slice_number]; % slice_order = [slice_number:-1:1]; slice_order = [slice_number:-1:1]; % preprocessing job display 'Creating preprocessing job' %在matlab的命令列視窗顯示Creating preprocessing job matlabbatch{1}.spm.spatial.realign.estwrite.data = {funcfiles{1,1}(:,1)};%這裡不加1 也行 ,就是上面查詢的時候 %% matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.quality = 0.9; matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.sep = 4; matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.fwhm = 5; matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.rtm = 1; matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.interp = 2; matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.wrap = [0 0 0]; matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.weight = ''; matlabbatch{1}.spm.spatial.realign.estwrite.roptions.which = [2 1]; matlabbatch{1}.spm.spatial.realign.estwrite.roptions.interp = 4; matlabbatch{1}.spm.spatial.realign.estwrite.roptions.wrap = [0 0 0]; matlabbatch{1}.spm.spatial.realign.estwrite.roptions.mask = 1; matlabbatch{1}.spm.spatial.realign.estwrite.roptions.prefix = 'r'; matlabbatch{2}.spm.temporal.st.scans{1}(1) = cfg_dep('Realign: Estimate & Reslice: Realigned Images (Sess 1)', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','sess', '()',{1}, '.','cfiles')); matlabbatch{2}.spm.temporal.st.nslices = slice_number; matlabbatch{2}.spm.temporal.st.tr = TR; matlabbatch{2}.spm.temporal.st.ta = TA; matlabbatch{2}.spm.temporal.st.so = slice_order; matlabbatch{2}.spm.temporal.st.refslice = slice_number/2; matlabbatch{2}.spm.temporal.st.prefix = 'a'; matlabbatch{3}.spm.spatial.coreg.estimate.ref(1) = cfg_dep('Realign: Estimate & Reslice: Mean Image', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','rmean')); matlabbatch{3}.spm.spatial.coreg.estimate.source = {anatfile};%ananfile 字串末尾得加一個1,細看對比stupid_batch_nii_third_formal_compilable matlabbatch{3}.spm.spatial.coreg.estimate.other = {''}; matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.cost_fun = 'nmi'; matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.sep = [4 2]; matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.tol = [0.02 0.02 0.02 0.001 0.001 0.001 0.01 0.01 0.01 0.001 0.001 0.001]; matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.fwhm = [7 7]; matlabbatch{4}.spm.spatial.preproc.channel.vols(1) = cfg_dep('Coregister: Estimate: Coregistered Images', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','cfiles')); matlabbatch{4}.spm.spatial.preproc.channel.biasreg = 0.001; matlabbatch{4}.spm.spatial.preproc.channel.biasfwhm = 60; matlabbatch{4}.spm.spatial.preproc.channel.write = [0 1]; matlabbatch{4}.spm.spatial.preproc.tissue(1).tpm = {'C:\Program Files\MATLAB\R2021b\toolbox\spm12\tpm\TPM.nii,1'}; matlabbatch{4}.spm.spatial.preproc.tissue(1).ngaus = 1; matlabbatch{4}.spm.spatial.preproc.tissue(1).native = [1 0]; matlabbatch{4}.spm.spatial.preproc.tissue(1).warped = [0 0]; matlabbatch{4}.spm.spatial.preproc.tissue(2).tpm = {'C:\Program Files\MATLAB\R2021b\toolbox\spm12\tpm\TPM.nii,2'}; matlabbatch{4}.spm.spatial.preproc.tissue(2).ngaus = 1; matlabbatch{4}.spm.spatial.preproc.tissue(2).native = [1 0]; matlabbatch{4}.spm.spatial.preproc.tissue(2).warped = [0 0]; matlabbatch{4}.spm.spatial.preproc.tissue(3).tpm = {'C:\Program Files\MATLAB\R2021b\toolbox\spm12\tpm\TPM.nii,3'}; matlabbatch{4}.spm.spatial.preproc.tissue(3).ngaus = 2; matlabbatch{4}.spm.spatial.preproc.tissue(3).native = [1 0]; matlabbatch{4}.spm.spatial.preproc.tissue(3).warped = [0 0]; matlabbatch{4}.spm.spatial.preproc.tissue(4).tpm = {'C:\Program Files\MATLAB\R2021b\toolbox\spm12\tpm\TPM.nii,4'}; matlabbatch{4}.spm.spatial.preproc.tissue(4).ngaus = 3; matlabbatch{4}.spm.spatial.preproc.tissue(4).native = [1 0]; matlabbatch{4}.spm.spatial.preproc.tissue(4).warped = [0 0]; matlabbatch{4}.spm.spatial.preproc.tissue(5).tpm = {'C:\Program Files\MATLAB\R2021b\toolbox\spm12\tpm\TPM.nii,5'}; matlabbatch{4}.spm.spatial.preproc.tissue(5).ngaus = 4; matlabbatch{4}.spm.spatial.preproc.tissue(5).native = [1 0]; matlabbatch{4}.spm.spatial.preproc.tissue(5).warped = [0 0]; matlabbatch{4}.spm.spatial.preproc.tissue(6).tpm = {'C:\Program Files\MATLAB\R2021b\toolbox\spm12\tpm\TPM.nii,6'}; matlabbatch{4}.spm.spatial.preproc.tissue(6).ngaus = 2; matlabbatch{4}.spm.spatial.preproc.tissue(6).native = [0 0]; matlabbatch{4}.spm.spatial.preproc.tissue(6).warped = [0 0]; matlabbatch{4}.spm.spatial.preproc.warp.mrf = 1; matlabbatch{4}.spm.spatial.preproc.warp.cleanup = 1; matlabbatch{4}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; matlabbatch{4}.spm.spatial.preproc.warp.affreg = 'mni'; matlabbatch{4}.spm.spatial.preproc.warp.fwhm = 0; matlabbatch{4}.spm.spatial.preproc.warp.samp = 3; matlabbatch{4}.spm.spatial.preproc.warp.write = [0 1]; matlabbatch{4}.spm.spatial.preproc.warp.vox = NaN; matlabbatch{4}.spm.spatial.preproc.warp.bb = [NaN NaN NaN NaN NaN NaN]; matlabbatch{5}.spm.spatial.normalise.write.subj.def(1) = cfg_dep('Segment: Forward Deformations', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','fordef', '()',{':'})); matlabbatch{5}.spm.spatial.normalise.write.subj.resample(1) = cfg_dep('Realign: Estimate & Reslice: Resliced Images (Sess 1)', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','sess', '()',{1}, '.','rfiles')); matlabbatch{5}.spm.spatial.normalise.write.woptions.bb = [-78 -112 -70 78 76 85]; matlabbatch{5}.spm.spatial.normalise.write.woptions.vox = [2 2 2]; matlabbatch{5}.spm.spatial.normalise.write.woptions.interp = 4; matlabbatch{5}.spm.spatial.normalise.write.woptions.prefix = 'w'; matlabbatch{6}.spm.spatial.smooth.data(1) = cfg_dep('Normalise: Write: Normalised Images (Subj 1)', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('()',{1}, '.','files')); matlabbatch{6}.spm.spatial.smooth.fwhm = [8 8 8]; matlabbatch{6}.spm.spatial.smooth.dtype = 0; matlabbatch{6}.spm.spatial.smooth.im = 0; matlabbatch{6}.spm.spatial.smooth.prefix = 's'; % 儲存matlabbatch matfile = sprintf('preprocess_nii_%s.mat', subjects{csubj}); % save(matfile,'matlabbatch'); jobs{csubj} = matfile; %jobs這個變數中儲存了所有被試的matlabbatch ['Start preprocessing job' num2str(csubj)] spm_jobman('run', matlabbatch); end %% % 執行預處理的工作 % for csubj = 15:20 % display 'Start preprocessing job' %在matlab的命令列視窗顯示Start preprocessing job % load(jobs{csubj}); % spm_jobman('run', matlabbatch); % end