# Pre-processing segmentation mask

**URL:** <https://discourse.itk.org/t/pre-processing-segmentation-mask/5530>\
**Category:** Uncategorized\
**Tags:** 3d, dicom, ct, simpleitk, python\
**Created:** [November 29, 2022, 7:43pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530 "2022-11-29T19:43:07Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![DushiFdo](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/c68b51/32.png) [@DushiFdo](https://discourse.itk.org/u/DushiFdo)\
**Post date:** [November 29, 2022, 7:43pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/1 "2022-11-29T19:43:08Z")

</div>

I am working with 3D CT images (Dicoms), and I performed several pre-processing steps on the input images such as resampling, normalizing, removing noise, crop image, resizing, crop center and reshaping to (128, 128, 128). I have constructed the 3D segmentation masks (saved as a 3D numpy image) with shape same as the original input image (512,512, x), where x is the number of slices that varies from image to image. How should I pre-process the segmentation mask so that it corresponds iwth the processed input image? Should I register input image and mask? Is there a simple way to do this in sitk?

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [November 29, 2022, 8:15pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/2 "2022-11-29T20:15:40Z")

</div>

Hello @DushiFdo,

Possibly consider using [TorchIO](https://torchio.readthedocs.io/index.html), highly recommended.

If you want to implement your own, then all you need to do is apply the same **spatial transformations** to the segmentation mask (remember that when doing resampling you will want to use the `sitk.sitkNearestNeighbor` interpolator). See [this Jupyter notebook](https://github.com/InsightSoftwareConsortium/SimpleITK-Notebooks/blob/master/Python/70_Data_Augmentation.ipynb), function titled `augment_images_spatial` and the parameter of interest is `additional_image_information`.

---

<div class="post-metadata">

**Author:** ![DushiFdo](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/c68b51/32.png) [@DushiFdo](https://discourse.itk.org/u/DushiFdo)\
**Post date:** [November 29, 2022, 8:32pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/3 "2022-11-29T20:32:26Z")

</div>

Thank you. I am not familiar with pytorch so will have to implement my own. The masks I created are numpy arrays, so I guess it won’t have the same information as an Dicom image. So, I am just wondering how I should I proceed in this case?

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [November 29, 2022, 8:41pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/4 "2022-11-29T20:41:25Z")

</div>

Hello @DushiFdo,

Assuming you have a CT/MR as a SimpleITK image, let us call it `image` and you have a corresponding mask as a numpy array, let us call it `arr`:

```auto
mask = sitk.GetImageFromArray(arr)
mask.CopyInformation(image)
#Confirm that image and mask are aligned, save both to mha files and 
#open in ITK-SNAP

# Use same set of spatial operations on the mask as applied to the image, 
# with the only difference being that we use sitkNearestNeighbor when 
# resampling instead of sitkLinear

```

---

<div class="post-metadata">

**Author:** ![DushiFdo](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/c68b51/32.png) [@DushiFdo](https://discourse.itk.org/u/DushiFdo)\
**Post date:** [December 1, 2022, 2:43am UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/5 "2022-12-01T02:43:40Z")

</div>

Thank you so much @zivy. This worked. When resizing the segmentation mask into (128,128,128) after resampling, I use the following code:

```python
def resize_volume_mask(img):
    """Resize across z-axis"""
    # Set the desired depth
    desired_depth = 128 
    desired_width = 128 
    desired_height = 128 
    # Get current depth
    current_depth = img.shape[0] #-1
    current_width = img.shape[1] #0
    current_height = img.shape[2] #1
    # Compute depth factor
    depth = current_depth / desired_depth
    width = current_width / desired_width
    height = current_height / desired_height
    depth_factor = 1 / depth
    width_factor = 1 / width
    height_factor = 1 / height
    # Rotate
    #img = ndimage.rotate(img, 90, reshape=False)
    # Resize across z-axis
    img = ndimage.zoom(img, (depth_factor, width_factor, height_factor), order=1)
    return img

```

This generates a blurry image with a little different shape for segmentation mask and now the array has values not only 0 and 1, but a series of values between 0 and 1.

The segmentation mask looks as follows, before and after resizing it:  
Before:  
 ![image](https://discourse.itk.org/uploads/default/original/2X/9/90a5423d6d59fb14f46619184971389fa16058f5.png)  
After:  
 ![image](https://discourse.itk.org/uploads/default/original/2X/d/d27de24847cd3be66d7ca765a582e97acb30815b.png)

I tried the following as well, but the result was same as before.

```python
from skimage.transform import resize
image_resized_seg= resize(center_seg, (128, 128, 128), order=1)

```

Is there a way in _sitk_ to resize the binary segmentation mask, without distorting it?

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [December 1, 2022, 1:51pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/6 "2022-12-01T13:51:23Z")

</div>

Hello @DushiFdo,

You are using skimage, so this question should have been posted to the [skimage discourse](https://discuss.scientific-python.org/tag/skimage), not here.

Having said that, you need to change to `order=0`, nearest neighbor interpolation, maintaining the original values. `order=1` is linear interpolation so the result includes values that did not exist in the original data.

---

<div class="post-metadata">

**Author:** ![DushiFdo](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/c68b51/32.png) [@DushiFdo](https://discourse.itk.org/u/DushiFdo)\
**Post date:** [December 1, 2022, 3:45pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/7 "2022-12-01T15:45:13Z")

</div>

Thank you. I tried with `order=0` but this removed some slices containing segmentation mask when resizing. That’s why I’d like to do this on `sitk` instead of `skimage`. Is there a function to resize images in `sitk` (for example, from (564, 359, 359) to (128, 128, 128) without loss of information? Here the axis order is (z, x, y).

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [December 1, 2022, 4:13pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/8 "2022-12-01T16:13:18Z")

</div>

Hello @DushiFdo,

Yes, this can be done. Please see the [data augmentation notebook](https://github.com/InsightSoftwareConsortium/SimpleITK-Notebooks/blob/master/Python/70_Data_Augmentation.ipynb). The section titled **Create reference domain** , first code cell. After computing the reference image data you can just use that and call the `Resample` function using the nearest neighbor interpolator.

---

<div class="post-metadata">

**Author:** ![DushiFdo](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/c68b51/32.png) [@DushiFdo](https://discourse.itk.org/u/DushiFdo)\
**Post date:** [December 5, 2022, 8:54pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/9 "2022-12-05T20:54:04Z")

</div>

Hi @zivy, I followed the notebook you linked and created the reference image and then resampled as follows:

```python
data = sitk.GetImageFromArray(mask_npa)
dimension = data.GetDimension()

reference_spacing = np.ones(dimension)
reference_origin = np.zeros(dimension)
reference_direction = np.identity(dimension).flatten()
reference_size = [128] * dimension

reference_image = sitk.Image(reference_size, data.GetPixelIDValue())
reference_image.SetOrigin(reference_origin)
reference_image.SetSpacing(reference_spacing)
reference_image.SetDirection(reference_direction)
reference_center = np.array(
    reference_image.TransformContinuousIndexToPhysicalPoint(np.array(reference_image.GetSize()) / 2.0))

resampled_img = sitk.Resample(data, reference_image, sitk.Transform(), sitk.sitkNearestNeighbor, 0.0)

```

However, this just created an empty image (full black).

Attributes of both mask and reference image are as follows:

```auto
direction (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)
origin (0.0, 0.0, 0.0)
spacing (1.0, 1.0, 1.0)

```

Please let me know what needs to be changed. Thank You.

---

<div class="post-metadata">

**Author:** ![DushiFdo](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/c68b51/32.png) [@DushiFdo](https://discourse.itk.org/u/DushiFdo)\
**Post date:** [December 6, 2022, 7:31pm UTC](https://discourse.itk.org/t/pre-processing-segmentation-mask/5530/10 "2022-12-06T19:31:30Z")

</div>

Can someone please tell me what could be the reason for getting a full black image after resampling on to a reference image? I am basically trying to resize a segmentation map.
