Get dimensions of mask from .nii file

Hello,
I have to extract mask dimension from .nii files. There are two files, one is with medical image, second with mask created in 3D-slicer.

t1_fn = 'first_file.nii'
t2_fn = 'second_file_with_mask.nii'
sitk_t1 = sitk.ReadImage(t1_fn)
sitk_t2 = sitk.ReadImage(t2_fn)

t1 = sitk.GetArrayFromImage(sitk_t1)
t2 = sitk.GetArrayFromImage(sitk_t2)

print(t1.shape) #output: (208, 112, 112, 3)
print(t2.shape) #output: (208, 112, 112)

Loop through the files:

i_start = 20
i_end= 26
x=26
for i in range(i_start,i_end):
    plt.subplot(i_start,i_end ,i + 1)
    plt.imshow(t1[i], cmap='gray')
    plt.gcf().set_size_inches(50, 50)
plt.show()

for i in range(i_start,i_end):
    plt.subplot(i_start,i_end ,i + 1)
    plt.imshow(t2[i], cmap='gray')
    plt.gcf().set_size_inches(50, 50)

plt.show()

I would like to extract only the layer with a mask and get that polygon dimensions. Thank you for your help.

Hello @mik.ro,

Not sure what you mean by “get dimensions of mask”, possibly the mask’s bounding box?

If that is correct, then the class you are looking for is LabelShapeStatisticsImageFilter.
The code below illustrates how to use the filter and process the whole “video” (I’m assuming we are working with an US video which can have more than one mask at each time point - multiple objects of interest which were segmented):

import SimpleITK as sitk

file_name = "second_file_with_mask.nii"

segmentation = sitk.ReadImage(file_name)

label_shape_filter = sitk.LabelShapeStatisticsImageFilter()
label_shape_filter.SetBackgroundValue(0)

segmentation_information = []
for i in range(segmentation.GetDepth()): # go over all timepoints
    label_shape_filter.Execute(segmentation[:,:,i])
    if label_shape_filter.GetNumberOfLabels()>0:
        seg_info = {"timepoint":i}
        seg_info["stats"] = []
        for label in label_shape_filter.GetLabels(): # for each label in this timepoint
           label_stats = {"label":label}
           label_stats["bounding_box"] = label_shape_filter.GetBoundingBox(label)
           label_stats["number_of_pixels"] = label_shape_filter.GetNumberOfPixels(label)
           # add any additional shape information we are interested in (centroid, oriented bounding box, length of perimeter...) which is supported by the filter.
           seg_info["stats"].append(label_stats)
        segmentation_information.append(seg_info)

print(segmentation_information)

Thank you @zivy for your help, your code brings me near the solution. I assume that the mask can be treated as a polygon. I would like to get the corners of the polygon as x,y values.

Hello @mik.ro,

This is not as simple as you would think.

The closest thing you can do in SimpleITK is use the BinaryContourImageFilter and then get the coordinates of the contour, but these are not ordered, so you would be getting the border pixel locations but in random order.

In VTK this can be done using the vtkContourFilter. In OpenCV this can be done using the findContours function.

1 Like