This post shows the overview of doing bias field correction in in SPM. Doing this helps me a lot to improve the accuracy of FreeSurfer with MP2RAGE data. The members of Polimeni’s group also use it as an additional per-processing step before giving the data to Freesurfer.
The SPM bis field correction is part of the segmentation pipeline in SPM. I use the following bash script and the following matlab stript:
Bias_field_script_job.m and start_bias_field.sh.
Examples of both of them can be downloaded here: https://github.com/layerfMRI/repository/tree/master/bias_field_corr
You can run the Matlab script from the console with
cp $1 uncorr.nii cp /PathToMatlabScript/Bias_field_script_job.m ./Bias_field_script_job.m matlab -nodesktop -nosplash -r "Bias_field_script_job" 3dcalc -a muncorr.nii -prefix muncorr.nii -overwrite -expr 'a' -datum short rm uncorr.nii
The first line just renames the nii file to what the matlab scrip expects it to be.
The second line collects the matlab script and copies it to the location of the current working directory.
The third line executes the SPM script in matlab.
Since the output of SPM is in the datatype: double, the corresponding file size can be very large. Hence, the next line uses an afni command to convert it to short.
The content of the SPM script is:
matlabbatch{1}.spm.spatial.preproc.channel.vols = {'./uncorr.nii,1'}; matlabbatch{1}.spm.spatial.preproc.channel.biasreg = 0.001; matlabbatch{1}.spm.spatial.preproc.channel.biasfwhm = 60; matlabbatch{1}.spm.spatial.preproc.channel.write = [1 1]; matlabbatch{1}.spm.spatial.preproc.tissue(1).tpm ={'~/SPM/spm12/tpm/TPM.nii,1'}; matlabbatch{1}.spm.spatial.preproc.tissue(1).ngaus = 1; matlabbatch{1}.spm.spatial.preproc.tissue(1).native = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(1).warped = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(2).tpm = {'~SPM/spm12/tpm/TPM.nii,2'}; matlabbatch{1}.spm.spatial.preproc.tissue(2).ngaus = 1; matlabbatch{1}.spm.spatial.preproc.tissue(2).native = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(2).warped = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(3).tpm ={'~/SPM/spm12/tpm/TPM.nii,3'}; matlabbatch{1}.spm.spatial.preproc.tissue(3).ngaus = 2; matlabbatch{1}.spm.spatial.preproc.tissue(3).native = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(3).warped = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(4).tpm ={'~/SPM/spm12/tpm/TPM.nii,4'}; matlabbatch{1}.spm.spatial.preproc.tissue(4).ngaus = 3; matlabbatch{1}.spm.spatial.preproc.tissue(4).native = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(4).warped = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(5).tpm ={'~/SPM/spm12/tpm/TPM.nii,5'}; matlabbatch{1}.spm.spatial.preproc.tissue(5).ngaus = 4; matlabbatch{1}.spm.spatial.preproc.tissue(5).native = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(5).warped = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(6).tpm = {'/Users/huberl/SPM/spm12/tpm/TPM.nii,6'}; matlabbatch{1}.spm.spatial.preproc.tissue(6).ngaus = 2; matlabbatch{1}.spm.spatial.preproc.tissue(6).native = [0 0]; matlabbatch{1}.spm.spatial.preproc.tissue(6).warped = [0 0]; matlabbatch{1}.spm.spatial.preproc.warp.mrf = 1; matlabbatch{1}.spm.spatial.preproc.warp.cleanup = 0; matlabbatch{1}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; matlabbatch{1}.spm.spatial.preproc.warp.affreg = 'mni'; matlabbatch{1}.spm.spatial.preproc.warp.fwhm = 0; matlabbatch{1}.spm.spatial.preproc.warp.samp = 3; matlabbatch{1}.spm.spatial.preproc.warp.write = [0 0]; spm('defaults','FMRI') spm_jobman('initcfg'); spm_jobman('run',matlabbatch); exit
The resulting signal change looks as follows:
You can of course do it via the SPM -> FMRI -> Segmentation gui-batch in matlab
Thanks to Sri for tips.
Hi Renzo,
thank you very much for the post.
The recon -all command of Freesurfer includs the intensity normalization in the processing pipeline. So I am wondering why we need to do it again using spm before feeding the data to Freesurfer.
Best,
Hang
LikeLike
Hi Hang,
Freesurfer is a black box for me. So I can only give you an answer based on experience:
1.) I just compared it with and without previous SPM bias field correction. And the results are looking better WITH SPM bias field correction
2.) In the papers from the MGH group (E.g. Polimeni et al.) they also do it. They apply the SPM bias field correction despite having the best understanding of the internal working principle of freesurfer. So I trust them in what they do and copied their pipeline.
3.) As far as my naive understanding goes, I believe that freesurfer’s normalization is less local than the SPM bias field correction. While freesurfer scalles the entire image, SPM accounts for local B1-bias fields.
Best,
Renzo
LikeLike