Bias field correction

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:

bias.gif

You can of course do it via the SPM -> FMRI -> Segmentation gui-batch in matlab

Screenshot 2017-12-21 13.28.35.png

Thanks to Sri for tips.