Generate Spinal Cord mask over specific region (i.e. levels) of the spinal cord

Hi there!

I was wondering, is there a way that I can create a STRAIGHTENED spinal cord MASK, but only for specific levels of the spinal cord (e.g. from C3 to C7). For example, I have input 3D T1 weighted images as such:

and I would like to generate a mask something similar to this image right here:

Let’s say I want segmentation from C3 - C7. Is there an automatic way of getting that?


It depends what you would like to do with the brain still “attached” to the straightened spinal cord. If this is only for visual purpose (without any quantification on the spinal cord), there is the command sct_flatten_sagittal, which aligns the cord in the medial sagittal plane. If this is of interest to you, we could easily modify the function to also align the cord in the coronal plane. However, no quantification should be done with such “flattening” method (because the inner structure of the cord is compromised).

If, however, you wish to perform quantifications, then my next question would be: why do you need to keep the brain on? Keeping it on raises all sorts of questions regarding the validity of the anatomical consistency at the interface between the unstraightened brain and the straightened spinal cord. If you wish to perform a brain-spine study, then I strongly suggest to preprocess the brain and the spine separately: register the brain to the MNI template and the cord to the PAM50 template. Given that the PAM50 template is within the same coordinate system as the MNI template, you will be able to process both the brain and the cord as a “single” volume. See this post for more details: How to merge MNI and PAM50 template?

If, for some reasons, you really need to keep the brain on the straightened spinal cord, then the example below shows how to do it:

# Download example data
sct_download_data -d sct_example_data
cd sct_example_data/t1
# Segment cord
sct_deepseg_sc -i t1.nii.gz -c t1 -qc qc
# We add a single label at the top of the FOV, located at the center of the upper most X,Y coordinate of the center of mass of the upper most part of the cord segmentation. Note: the numbers below were found "manually", but if this feature is desired we can easily add it in future versions of SCT. 
sct_label_utils -i t1_seg.nii.gz -create-add 96,106,-1,1 -o t1_seg_top_vox.nii.gz
# Straighten spinal cord. The key here is to use the flag -xy-size with an appropriate value so the output straightened destination space can accommodate the inclusion of the brain.
sct_straighten_spinalcord -i t1.nii.gz -s t1_seg_top_vox.nii.gz -xy-size 192

Hi @jcohenadad! Thank you for your reply! Before discussing anything further, I just want to make it clear that I do NOT want to keep the brain, but for the input I do have images with brain and some portion (30mm or more) of the spinal cord. From those images I want to extract and straighten spinal cord only, which I can do by following:

sct_deepseg_sc -i 3dt1_w.nii.gz -c t1 -o 3dt1_sc_seg.nii.gz
sct_straighten_spinal_cord -i 3dt1_w.nii.gz -s 3dt1_sc_seg.nii.gz -ofolder straight

And as a result I get straightened spinal cord images. Now, what I actually need is not MASK over the ENTIRE spinal cord, but only specific portion (for example from C3 - C6). I have a lot of 3D T1 BRAIN images from which I am extracting spinal cord and need to have mask over the SAME region for each spinal cord so that I can do my analysis.

I hope I made my question more clear. The 2nd image in the question is an example of extracted spinal cord and created 15mm segmentation over a specific area. I would like to create similar segmentation for many images automatically.

Hi @Stefan_Radonjic,

If your goal is to get systematic measurements at, let’s say C3-C6, then you can use sct_label_vertebrae and then compute your metrics of interest within specific levels, using either sct_process_segmentation (if you are interested in segmentation-based metrics) and/or sct_extract_metric (if you are interested in qMRI metrics, such as DTI, MT, fMRI, etc.). For more details, please see the example script, and also the latest SCT course.

1 Like

Thank you for fast reply @jcohenadad!

So by utilizing these functionalities I can produce BINARY mask over C3-C6 region? I will investigate these links and let you know what I found out :slight_smile:

No. These functionalities are used to compute specific metrics using labeled information. If you want to produce a binary mask over C3-C6, then you can threshold and binarize the labeled segmentation. Example with fslmaths:

# Vertebral labeling with SCT
sct_label_vertebrae -i t1.nii.gz -s t1_seg.nii.gz -c t1
# Thresholding with FSL
fslmaths t1_seg_labeled.nii.gz -thr 3 -uthr 6 -bin t1_seg_labeled_c3c6.nii.gz

Screen Shot 2021-03-29 at 11.48.44 AM

:information_source: We will have the upper threshold feature in SCT soon (see Issue).

:warning: While the syntax above enables you to create a binary mask, we do not recommend using binary masks for extraction of metrics as it does not account for partial volume effects. For more details, see SCT course.


The above mentioned is exactly what I needed and it works :slight_smile: It would be nice to have such feature in SCT as well. Thank you :slight_smile:

1 Like

Hi @jcohenadad!

I have a question related to this topic. When I try to label STRAIGHTENED spine with sct_label_vertabrae, labeling seems “off”. What I mean is, I am trying to extract C2 region as binary mask, but on the first Image I think that C2 region is being labeled as C1, and that REAL C1 region is missing:

While on the other image labeling seems fine:

Any idea how can I fix this? I need same region from both images in order to proceed with my analysis. Thanks in advance!

NOTE: If I perform labeling on 3D T1 Brain images and THEN straighten the spine, I am getting similar issue, but not necessarily for the same images.

Hi @Stefan_Radonjic,

The labeling is off because the automatic C2-C3 disc identification failed. Straightened data might be more prone to failure because the model is not used to such data.

One thing you could do is perform labeling on the native image, and then apply the warp_curve2straight.nii.gz warping field on the labeling data using sct_apply_transfo (make sure to use nearest neighbour interpolation if you do that, as these are discrete labels).

Alternatively, you can initialize C2-C3 disc using the -initlabel flag.

Thanks for reply @jcohenadad!

I’ve already tried the approach where I apply the warp_curve2straight.nii.gz warping field with sct_apply_transfo with nn interpolation, but I get same issue only different image examples. Although, sometimes labeling does produce an error where it cannot detect C2-C3 disc. Those are the cases I skip. But the cases I showed you does not produce any error, even though C2-C3 disc identification clearly failed. Maybe this should be posted an issue as a bug?

Regarding the -initlabel flag, how is this feature used? It is manual I assume?

I’m sorry but there are a few things i do not understand from your explanation, so let me try to rephrase point-by-point:

  • You already tried to apply warp_curve2straight.nii.gz on vertebral labeling, but it did not produce satisfactory results because the vertebral labeling was wrong in the first place.
    :point_right: Indeed. If you apply warp_curve2straight.nii.gz on wrong labeling, then the labels warped on the straight space will also be wrong.
  • Sometimes, sct_label_vertebrae produces an error where it cannot detect C2-C3 disc.
    :point_right: That could indeed happen. This is where manual labeling is recommended (see below).
  • Other times, C2-C3 detection does not produce an error, but regardless labeling results are wrong (e.g., C2 is labeled as “C3”, C3 is labeled as “C4”, etc.). You are suggesting that this is a bug and it should be posted as an issue on SCT’s Github repository.
    :point_right: We are well aware that vertebral labeling is not perfect and sometimes fails. The performance of the algorithm strongly depends on the image feature (FOV, contrast, noise, artifact, syntax usage, etc.). On the spine-generic data, we noticed that automatic labeling failed in about 15% of the cases. We have implemented a more performant version of the labeling using deep learning, and the feature we will be available soon. For more details, see this PR.

Yes. You can get the manual labels using sct_label_utils -create-viewer. Example:

sct_label_utils -i IMAGE -create-viewer 3,4 -msg "Click at the posterior tip of intervertebral discs C2-C3 and C3-C4" 
1 Like

@jcohenadad thank you so much, you have been really helpful! The last point was the one that kept occurring in my situation, but in around 30% of the cases I was testing. Cant wait for new feature to come out!

Update: This feature has now been introduced as of SCT v5.4. :tada:

1 Like