How to Get Grey Matter Volume of Specific Brain Regions in SPM/MATLAB?
Show older comments
I want to extract grey matter volume for specific regions (e.g., prefrontal cortex, amygdala) from MRI data that has been preprocessed. My lab gave me a code (see below) for calculating global grey matter volume (and white matter volume and CSF), but I am not sure whether I can adapt this script to also extract regional grey matter volume. Would appreciate help!
% Get total volumes in mm3
grey_totals(i) = get_totals ([data_path num2str(subnum) '/c1' num2str(subnum) '.nii']);
white_totals(i) = get_totals ([data_path num2str(subnum) '/c2' num2str(subnum) '.nii']);
csf_totals(i) = get_totals ([data_path num2str(subnum) '/c3' num2str(subnum) '.nii']);
end
12 Comments
Karl
on 11 Feb 2024
It would be useful to have some additional information:
- How is the get_totals() function defined? In particular, what does it expect as input?
- In the example, does each .nii file correspond to a binary mask representing the named material?
- For each specific region in which you're interested, do you have an .nii file corresponding to a binary mask representing the region?
Arjun
on 12 Feb 2024
Karl
on 12 Feb 2024
Thanks for the additional information. I think that you should be able to adapt your example script to extract the regional greyscale matter volumes. I'd suggest trying first for a single region for a single subject, something like:
region_totals = get_totals([path_to_ROI_mask]);
where you set path_to_ROI_mask to be the path to one of the masks that you've created with WFU_PickAtlas.
If the above doesn't work, or gives an answer that's obviously wrong, could you upload an example mask file? If it does work, it should then just be a case of naming your mask files, and organising in folders, so that you can process masks for all subjects in a loop. (I'm guessing that i in the example is a loop index.)
Arjun
on 12 Feb 2024
Thanks for uploading the example NIfTI mask. After unzipping, the code:
info = niftiinfo('Amygdala_mask.nii');
mask = niftiread(info);
volshow(mask);
gives:

and the volume in cubic millimetres is:
volume = sum(mask(:)) * prod(info.PixelDimensions)
This is one way of obtaining the region volume, but using get_totals() should also work. In your code, the path to the data doesn't look right. If the (unzipped) mask file were in the folder from which you run MATLAB, you should be able to use:
amygdala_totals = get_totals('Amygdala_mask.nii');
In general, you might not be running MATLAB from the folder where you have your data, so you'd need something like:
amygdala_totals = get_totals('/path/to/my/data/Amygdala_mask.nii');
In case useful, there's some information about file paths in the documentation:
Arjun
on 13 Feb 2024
The error comes from trying to access amygdala_totals as anything other than a scalar - the same as the following:
amygdala_totals = 3.744;
x = amygdala_totals('path');
Could you try running just the following:
%get SPM12
addpath '/Users/arjunthanaraju/Downloads/PhD/spm12/';
%obtain volume of amygdala
amygdala_totals = get_totals(['/Volumes/SEAGATE_BAC/Amygdala_Mask.nii']);
disp(['Volume of amygdala = ', num2str(amygdala_totals), ' (units to be checked)']);
This should hopefully confirm that the basic volume calculation is working for you.
Arjun
on 14 Feb 2024
Karl
on 14 Feb 2024
Excellent! A possible next step would be to organise the ROI masks for which you want to extract volume information in a way that makes them easy to analyse.
In the example code that you have, there's a folder for each subject, and each subject folder contains multiple ROI masks. You could do something similar. For example, if the first subject has identifier 12345, you could create a folder /Volumes/SEAGATE_BAC/397Participants/12345, and inside that place the ROI masks, for example amygdala_12345.nii, some_other_roi_12345.nii.
You could then loop over subjects, extracting volumes for each ROI. If in your code:
subnum = files_mri(i).name;
correctly defines the subject identifier, you should be able to obtain volumes with lines like:
amygdala_totals(i) = get_totals(['/Volumes/SEAGATE_BAC/397Participants/' num2str(subnum) '/amygdala_' num2str(subnum) '.nii']);
some_other_roi_totals(i) = get_totals(['/Volumes/SEAGATE_BAC/397Participants/' num2str(subnum) '/some_other_roi_' num2str(subnum) '.nii']);
You'd then change the definition of the globals table to reflect the ROIs for which you have data.
Arjun
on 19 Feb 2024
Karl
on 19 Feb 2024
You're welcome! If you're unable to get the looping to work, please do submit another question, ideally including code and files for reproducing the problem (as you did in the comments here). Hopefully I, or someone else, will be able to help!
Arjun
on 20 Feb 2024
Accepted Answer
More Answers (0)
Categories
Find more on Biomedical Imaging in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!