Main Content

Segment and Analyze Brain MRI Scan Using AI

Since R2024a

This example shows how to preprocess, label, postprocess, and analyze a brain MRI image using MONAI Label.

In this example, you apply the wholeBrainSeg Large UNEST segmentation model [1] from the Medical Open Network for AI (MONAI) Label library. The MONAI Label [2][3] platform provides fully automated and interactive deep learning models for segmenting radiology images, and you can connect to MONAI Label from within the Medical Image Labeler app. To achieve satisfactory results from the wholeBrainSeg Large UNEST segmentation model, you must preprocess your data by registering it to an MNI305 atlas [4], which is a standardized brain atlas commonly used in neuroimaging analysis. In this example, you register the brain MRI data to the MNI305 atlas, segment it using the MONAI Label model, and transform the labels back to MRI space to calculate regional brain volumes.

Import Brain MRI Data

Import the brain MRI scan as a medicalVolume object. The MRI volume is from the CANDI data set [5] [6], and the 2.3 MB scan is attached to this example as a supporting file.

medVolMRI = medicalVolume("brainSegData_anat.nii.gz")
medVolMRI = 
  medicalVolume with properties:

                 Voxels: [256×256×128 int16]
         VolumeGeometry: [1×1 medicalref3d]
           SpatialUnits: "mm"
            Orientation: "coronal"
           VoxelSpacing: [0.9375 0.9375 1.5000]
           NormalVector: [0 -1 0]
       NumCoronalSlices: 128
      NumSagittalSlices: 256
    NumTransverseSlices: 256
           PlaneMapping: ["sagittal"    "transverse"    "coronal"]
               Modality: "unknown"
          WindowCenters: 0
           WindowWidths: 0

Display the brain MRI scan as 3-D slice planes.

volshow(medVolMRI,RenderingStyle="SlicePlanes")

Import Brain MNI Atlas

Import the MNI305 atlas image as a medicalVolume object. The atlas is attached to this example as a supporting file, and is approximately 2.8 MB.

atlas = medicalVolume("tpl-MNI305_T1w.nii.gz")
atlas = 
  medicalVolume with properties:

                 Voxels: [172×220×156 int16]
         VolumeGeometry: [1×1 medicalref3d]
           SpatialUnits: "mm"
            Orientation: "transverse"
           VoxelSpacing: [1 1 1]
           NormalVector: [0 0 1]
       NumCoronalSlices: 220
      NumSagittalSlices: 172
    NumTransverseSlices: 156
           PlaneMapping: ["sagittal"    "coronal"    "transverse"]
               Modality: "unknown"
          WindowCenters: 0
           WindowWidths: 0

Display the MNI atlas image as 3-D slice planes.

volshow(atlas,RenderingStyle="SlicePlanes")

Register MRI to Atlas

Resample the brain MRI image so that it has the same voxel spacing as the brain atlas.

dataresampled = resample(medVolMRI,atlas.VolumeGeometry);

Register the resampled brain MRI scan to the atlas image using intensity-based registration. To obtain the transformation matrix that describes the registration, use the imregtform function. Specify the transformation type as "affine" so the registration includes translation, rotation, and anisotropic scaling.

[optimizer,metric] = imregconfig("multimodal");
tform = imregtform(dataresampled.Voxels,atlas.Voxels, ...
    "affine",optimizer,metric);

The tform object describes the transformation from the MRI image to the atlas. Apply the transformation to the resampled MRI image using imwarp. Specify the output view so the size and location of the transformed image matches the atlas.

movingRegisteredVolume = imwarp(dataresampled.Voxels,tform, ...
    "OutputView",imref3d(size(atlas.Voxels)));

Create a medicalVolume object that contains the transformed MRI voxel data and the spatial referencing of the MNI atlas.

medVolRegistered = medicalVolume(movingRegisteredVolume,atlas.VolumeGeometry);

Load Registered MRI into Medical Image Labeler

In this section you load the MRI scan, which has been transformed into MNI space, into the Medical Image Labeler app and perform segmentation using a MONAI Label deep learning network.

Open Medical Image Labeler

Open the Medical Image Labeler app from the Apps tab on the MATLAB® Toolstrip, under Image Processing and Computer Vision. You can also load the app by using the medicalImageLabeler command.

Create New Volume Labeling Session

To start a new 3-D labeling session, on the app toolstrip, click New Session and select New Volume Session (3-D). In the Create a new session folder dialog box, specify a location in which to save the new session folder by entering a path, or select Browse and navigate to your desired location. In the New Session Folder dialog box, specify a name for the folder for this labeling session. Then, select Create Session.

Import MRI Volume

To load the registered MRI volume into the app, on the app toolstrip, click Import, and, under Data, select medicalVolume Object. In the dialog box that opens, select medVolRegistered and click OK.

The medicalVolume Object dialog box, with the medVolRegistered variable selected for import

The registered MRI volume appears in the app.

Medical Image Labeler app window after importing the registered MRI volume

Segment MRI Volume

Start MONAI Label

On the MONAI Label tab of the app toolstrip, select Start MONAI Label > On the local machine. If this is the first time you are connecting to a local server, Medical Image Labeler prompts you to install the Medical Imaging Toolbox Interface for MONAI Label Library support package, which includes the MONAI Label software. Follow the link in the dialog box to open the Add-On Explorer. To learn more about connecting to MONAI Label, see Get Started with MONAI Label in Medical Image Labeler. For more information about installing add-ons, see Get and Manage Add-Ons. When you install the support package, MATLAB downloads the MONAI Label models, which requires an internet connection.

Once the installation is complete, try starting MONAI Label again. You do not need to restart the app.

Choose Brain MRI Segmentation Model

To select the brain segmentation model, on the MONAI Label tab of the app toolstrip, from the Deep Learning Models gallery, select the wholeBrainSeg Large UNEST segmentation model.

Medical Image Labeler app window, showing how to select the wholeBrainSeg Large UNEST segmentation model

Perform Label Mapping

Use the Label Mapping dialog box to map labels predicted by the MONAI Label model to labels in the Label Definitions pane of the Medical Image Labeler app. In the dialog box, click Select All to pick all the labels. In the Label Definition in App column, the default <Create New> option enables the app to create new label definitions. Click OK to save your choices. The new labels appear in the Label Definitions pane of the app window.

Label Mapping dialog box, showing all labels for the brain segmentation model selected for prediction

Run the Model

In the app toolstrip, select Run. When the model finishes, the slice planes update to show the predicted labels. Overall, the results look satisfactory. This example uses the initial labels, and removes noise near the image boundary during postprocessing. For your data and application, you can choose to manually clean labels inside the brain using any of the manual or semi-automated drawing tools in the app.

Medical Image Labeler app window with brain labels predicted using MONAI Label

Export Ground Truth

From the Labeler tab of the app toolstrip, select Export, and, under Ground Truth, select To File. Specify the location to save the ground truth using the Export Ground Truth dialog box, and click Save. The app exports a groundTruthMedical object in the MAT file format.

Postprocess Results

Import Ground Truth

This example creates a new groundTruthMedical object that simulates you exporting results from the app to your local machine. Create the ground truth object using the createGroundTruthMed helper function, which is defined at the end of this example.

gTruthMed = createGroundTruthMed;

Alternatively, if you complete the previous sections and export your own groundTruthMedical object to the file location gTruthFileName, load the object using this code.

load(gTruthFileName)

Import the label data from the ground truth as a medicalVolume object.

labelVol = medicalVolume(gTruthMed.LabelData);

Display the registered brain MRI image as fully transparent, with the MONAI-predicted labels as an opaque overlay. As expected, the MRI data and labels are aligned.

volshow(medVolRegistered, ...
    alphamap=0, ...
    OverlayData=labelVol.Voxels, ...
    OverlayAlpha=0.5);

Remove the noisy voxels at the edge of the slices by using the filterNoisyVoxels helper function defined at the end of the example. The helper function loops through each label definition, and keeps only the largest connected component for that label.

numLabels = size(gTruthMed.LabelDefinitions,1);
labelVolFilt = filterNoisyVoxels(labelVol,numLabels);

Display the postprocessed labels. As desired, the noisy voxels have been removed.

volshow(medVolRegistered, ...
    alphamap=0, ...
    OverlayData=labelVolFilt.Voxels, ...
    OverlayAlpha=0.5)

You can more closely inspect the internal postprocessed labels using the slice planes rendering style.

volshow(medVolRegistered, ...
    RenderingStyle="SlicePlanes", ...
    OverlayData=labelVolFilt.Voxels)

Transform Labels Back to MRI Space from MNI Space

The labelVolFilt volume is in the MNI space. To transform the labels back to the original brain MRI space, apply the inverse of tform to the labels. Specify the interpolation method as "nearest", which is the appropriate value for categorical label data to prevent rounding artifacts at the edges of label regions.

tformInv = invert(tform);
labelVolMRI = imwarp(labelVolFilt.Voxels,tformInv,"nearest", ...
    OutputView=imref3d(size(dataresampled.Voxels)));

Create a medicalVolume object containing the labels in MRI space with the same spatial referencing as the unregistered, resampled Brain MRI image.

medVolLabelsMRI = medicalVolume(labelVolMRI,dataresampled.VolumeGeometry);

Resample the labels back to the original voxel spacing of the MRI scan.

medVolLabelsMRI = resample(medVolLabelsMRI,medVolMRI.VolumeGeometry,Method="nearest");

Display the original MRI scan with the transformed, resampled labels as an overlay.

volshow(medVolMRI, ...
    RenderingStyle="SlicePlanes", ...
    OverlayData=medVolLabelsMRI.Voxels)

Analyze Segmented MRI Volume

Calculate the volume of different brain structures and the overall brain volume. First, you must get the label names, which are stored in the LabelDefinitions field of the groundTruthMedical object.

labelDefs = gTruthMed.LabelDefinitions
labelDefs=132×3 table
                 Name                          LabelColor            PixelLabelID
    _______________________________    __________________________    ____________

    "x3rd_ventricle"                   0.0667    0.4431    0.7451          1     
    "x4th_ventricle"                   0.8667    0.3294         0          2     
    "right_accumbens_area"             0.9294    0.6941    0.1255          3     
    "left_accumbens_area"              0.5216    0.0863    0.8196          4     
    "right_amygdala"                   0.2314    0.6667    0.1961          5     
    "left_amygdala"                    0.1843    0.7451    0.9373          6     
    "brain_stem"                       0.8196    0.0157    0.5451          7     
    "right_caudate"                    0.3804    0.0353    0.0314          8     
    "left_caudate"                          1     0.851    0.7176          9     
    "right_cerebellum_exterior"         0.702    0.5333    0.1647         10     
    "left_cerebellum_exterior"         0.8392    0.5804         1         11     
    "right_cerebellum_white_matter"    0.7961         1    0.7451         12     
    "left_cerebellum_white_matter"     0.0902    0.4627    0.6471         13     
    "right_cerebral_white_matter"       0.949    0.4039    0.7725         14     
    "left_cerebral_white_matter"       0.7176    0.1922    0.1725         15     
    "right_hippocampus"                0.7882    0.9059         1         16     
      ⋮

Extract the label names to a new table for volume results.

results = labelDefs(:,"Name");

Calculate the number of voxels in each label using the regionprops3 function.

S = regionprops3(medVolLabelsMRI.Voxels,"Volume");
numVoxels = S.Volume;

To calculate the volume of each voxel, in cubic centimeters, convert the voxel spacing from mm to cm, and then multiply the spacing in all three directions. Then, calculate the volume of each label in cubic centimeters.

dv = prod(0.1*medVolMRI.VoxelSpacing);
volume = numVoxels.*dv;

Append the volume values to the results table.

results.("Volume (voxels)") = numVoxels;
results.("Volume (ccm)")= volume
results=132×3 table
                 Name                  Volume (voxels)    Volume (ccm)
    _______________________________    _______________    ____________

    "x3rd_ventricle"                           1280          1.6875   
    "x4th_ventricle"                           1935           2.551   
    "right_accumbens_area"                      340         0.44824   
    "left_accumbens_area"                       522         0.68818   
    "right_amygdala"                            925          1.2195   
    "left_amygdala"                             959          1.2643   
    "brain_stem"                              14316          18.874   
    "right_caudate"                            2825          3.7244   
    "left_caudate"                             2616          3.4488   
    "right_cerebellum_exterior"               39791          52.459   
    "left_cerebellum_exterior"                40408          53.272   
    "right_cerebellum_white_matter"           13666          18.017   
    "left_cerebellum_white_matter"            15885          20.942   
    "right_cerebral_white_matter"        1.6616e+05          219.06   
    "left_cerebral_white_matter"          1.688e+05          222.54   
    "right_hippocampus"                        3202          4.2214   
      ⋮

Calculate the total brain volume, in cubic centimeters. The total brain volume is 1446 cubic cm, which is in the normal range for human brain volume [7].

totalBrainVol = sum(volume)
totalBrainVol = 
1.4462e+03

Supporting Function

The filterNoisyVoxels helper function removes small clusters of noisy label voxels using these steps:

  1. While looping through each of the labels, create a binary mask for the current label.

  2. Find the connected components in the mask by using the bwconncomp function with a connectivity value of 6.

  3. Calculate the number of voxels in each connected component using the numel function.

  4. Determine the indices of voxels in the connected component with the most voxels.

  5. Set all label values for voxels outside the largest connected component to 0, which is the background. This step removes the small noisy voxels.

function labelVolFilt = filterNoisyVoxels(labelVol,numLabels)

labelVolFilt = labelVol;

for i = 1:numLabels

    maskLabel_i = labelVol.Voxels==i;
    CC = bwconncomp(maskLabel_i,6);
    numPixels = cellfun(@numel,CC.PixelIdxList); 
    [~,idx] = max(numPixels);
    maskLabel_i(CC.PixelIdxList{idx}) = 0;

    labelVolFilt.Voxels(maskLabel_i==1) = 0;

end
end

The createGroundTruthMed helper function creates a groundTruthMedical object that points to the label results on your local machine. The files used to create the ground truth object are all attached to this example as supporting files. You can also create them yourself by following the processes in the Import Brain MRI Data, Import Brain MNI Atlas, Register MRI to Atlas, Load Registered MRI into Medical Image Labeler, and Segment MRI Volume sections of this example, and exporting a groundTruthMedical object from the app.

function gTruthMed = createGroundTruthMed

dataFile = {"registeredVol.nii.gz"};
dataSource = medical.labeler.loading.VolumeSource(dataFile);
labelData = "medicalVolumeData.nii";
load("labelDefinitions.mat");

gTruthMed = groundTruthMedical(dataSource,labelDefinitions,labelData);

end

References

[1] Yu, Xin, Qi Yang, Yinchi Zhou, Leon Y. Cai, Riqiang Gao, Ho Hin Lee, Thomas Li, et al. “UNesT: Local Spatial Representation Learning with Hierarchical Transformer for Efficient Medical Segmentation.” Medical Image Analysis 90 (December 1, 2023): 102939. https://doi.org/10.1016/j.media.2023.102939.

[2] Diaz-Pinto, Andres, Sachidanand Alle, Vishwesh Nath, Yucheng Tang, Alvin Ihsani, Muhammad Asad, Fernando Pérez-García, et al. “MONAI Label: A Framework for AI-Assisted Interactive Labeling of 3D Medical Images,” 2022. https://doi.org/10.48550/ARXIV.2203.12362.

[3] Diaz-Pinto, Andres, Pritesh Mehta, Sachidanand Alle, Muhammad Asad, Richard Brown, Vishwesh Nath, Alvin Ihsani, et al. “DeepEdit: Deep Editable Learning for Interactive Segmentation of 3D Medical Images.” In Data Augmentation, Labelling, and Imperfections, edited by Hien V. Nguyen, Sharon X. Huang, and Yuan Xue, 11–21. Lecture Notes in Computer Science. Cham: Springer Nature Switzerland, 2022. https://doi.org/10.1007/978-3-031-17027-0_2.

[4] Evans, A.C., D.L. Collins, S.R. Mills, E.D. Brown, R.L. Kelly, and T.M. Peters. “3D Statistical Neuroanatomical Models from 305 MRI Volumes.” In 1993 IEEE Conference Record Nuclear Science Symposium and Medical Imaging Conference, 1813–17. San Francisco, CA, USA: IEEE, 1993. https://doi.org/10.1109/NSSMIC.1993.373602.

[5] “NITRC: CANDI Share: Schizophrenia Bulletin 2008: Tool/Resource Info.” Accessed October 17, 2022. https://www.nitrc.org/projects/cs_schizbull08/.

[6] Frazier, J. A., S. M. Hodge, J. L. Breeze, A. J. Giuliano, J. E. Terry, C. M. Moore, D. N. Kennedy, et al. “Diagnostic and Sex Effects on Limbic Volumes in Early-Onset Bipolar Disorder and Schizophrenia.” Schizophrenia Bulletin 34, no. 1 (October 27, 2007): 37–46. https://doi.org/10.1093/schbul/sbm120.

[7] Kijonka, Marek, Damian Borys, Krzysztof Psiuk-Maksymowicz, Kamil Gorczewski, Piotr Wojcieszek, Bartosz Kossowski, Artur Marchewka, Andrzej Swierniak, Maria Sokol, and Barbara Bobek-Billewicz. “Whole Brain and Cranial Size Adjustments in Volumetric Brain Analyses of Sex- and Age-Related Trends.” Frontiers in Neuroscience 14 (April 3, 2020). https://doi.org/10.3389/fnins.2020.00278.

See Also

Related Topics