# Best way to create same domain size for segmentation masks and 3D .nrrd files?

**URL:** https://discourse.slicer.org/t/best-way-to-create-same-domain-size-for-segmentation-masks-and-3d-nrrd-files/39608
**Category:** Development
**Tags:** segmentation, segmentations, segment-editor
**Created:** [October 9, 2024, 12:10pm UTC](https://discourse.slicer.org/t/best-way-to-create-same-domain-size-for-segmentation-masks-and-3d-nrrd-files/39608 "2024-10-09T12:10:00Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Yue-Hin\_Loke1](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/yue-hin_loke1/32/78169_2.png) [@Yue-Hin\_Loke1](https://discourse.slicer.org/u/Yue-Hin_Loke1)
#### Post date: [October 9, 2024, 12:10pm UTC](https://discourse.slicer.org/t/best-way-to-create-same-domain-size-for-segmentation-masks-and-3d-nrrd-files/39608/1 "2024-10-09T12:10:01Z")

</div>

Hi all,

I have a series of 3D .nrrd files of MRI images and corresponding segmentation masks that I created from slicer that I am hoping to train for autosegmentation.

I am trying to prepare the data by make them share the same coordinates/domain size, but I’m struggling due to if there are more than differences RAS (for 3D .nrrd files) vs. LPS coordinates (for the segmentation masks), even when I get the metadata for both. Any advice on the best way of approaching this issue? Thanks!

```python
import SimpleITK as sitk
import numpy as np

# Load MRI and label images
volume_image = sitk.ReadImage('Pros Normal 002.nrrd')
label_image = sitk.ReadImage('Pros Normal 002.seg.nrrd')

# Convert images to arrays for processing
volume_array = sitk.GetArrayFromImage(volume_image)
label_array = sitk.GetArrayFromImage(label_image)

# Get metadata from label image
label_shape = label_array.shape
label_origin = label_image.GetOrigin()
label_spacing = label_image.GetSpacing()

# Calculate the bounding box of the label
non_zero_indices = np.argwhere(label_array)
label_bbox_min = non_zero_indices.min(axis=0) # min (z_min, y_min, x_min)
label_bbox_max = non_zero_indices.max(axis=0) + 1 # max (z_max, y_max, x_max)

# Define ROI start based on label's bounding box in RAS coordinates
roi_start = [
    int(label_bbox_min[0]),
    int(label_bbox_min[1]),
    int(label_bbox_min[2])
]

# Define size based on label's bounding box dimensions
roi_size = [
    int(label_bbox_max[0] - label_bbox_min[0]),
    int(label_bbox_max[1] - label_bbox_min[1]),
    int(label_bbox_max[2] - label_bbox_min[2])
]

# Adjust roi_start for RAS coordinates
# Negate x and y indices for conversion from LPS to RAS
roi_start[1] = volume_array.shape[1] - roi_start[1] # Adjust y-coordinate
roi_start[2] = volume_array.shape[2] - roi_start[2] # Adjust x-coordinate

# Crop the volume using SimpleITK
cropped_volume = sitk.RegionOfInterest(volume_image, size=roi_size, index=roi_start)

# Save the cropped volume
sitk.WriteImage(cropped_volume, 'C:/Machine Learning/cropped_images/Pros_Normal_002_cropped.nrrd')

# Print out metadata
print("Label Shape:", label_shape)
print("Label Origin (world coordinates):", label_origin)
print("Cropped Volume Origin (world coordinates):", cropped_volume.GetOrigin())
print("Cropped Volume Size:", cropped_volume.GetSize())

```

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [October 9, 2024, 12:52pm UTC](https://discourse.slicer.org/t/best-way-to-create-same-domain-size-for-segmentation-masks-and-3d-nrrd-files/39608/2 "2024-10-09T12:52:02Z")

</div>

You can run this code snippet in Slicer’s Python environment to resample and crop/pad the segmentation to exactly match a reference volume’s geometry:

```python
referenceVolumeNode = slicer.util.loadVolume("c:/tmp/image.nrrd")
segmentationNode = slicer.util.loadSegmentation("c:/tmp/segmentation.seg.nrrd")

# Set segmentation's geometry (origin, spacing, axis direction, extents) to the reference image geometry
# (it does not resample existing segments)
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(referenceVolumeNode)

# Resample existing segments to the reference image geometry
segGeomLogic = slicer.vtkSlicerSegmentationGeometryLogic()
segGeomLogic.SetInputSegmentationNode(segmentationNode)
segGeomLogic.SetSourceGeometryNode(referenceVolumeNode)
segGeomLogic.SetPadOutputGeometry(False)
segGeomLogic.CalculateOutputGeometry()
segGeomLogic.ResampleLabelmapsInSegmentationNode()

slicer.util.saveNode(segmentationNode, "c:/tmp/resampled-segmentation.seg.nrrd")

```

---

<div class="post-metadata">

### Author: ![Denis\_Samatov](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/denis_samatov/32/82850_2.png) [@Denis\_Samatov](https://discourse.slicer.org/u/Denis_Samatov)
#### Post date: [September 24, 2026, 6:55am UTC](https://discourse.slicer.org/t/best-way-to-create-same-domain-size-for-segmentation-masks-and-3d-nrrd-files/39608/3 "2026-09-24T06:55:11Z")

</div>

Hi @Yue-Hin_Loke1 — your Slicer-to-ML example showed how hard it is to reason about cropped `.seg.nrrd` masks and image coordinates. The posted Slicer resample-to-reference code may remove the need to flip NumPy indices manually; I would want to verify the output in physical space before using it for training. Did that code solve your case, and which part remained hardest to trust: the coordinate convention, reference extent, interpolation, or visual verification? A short description or tiny synthetic example is sufficient; no original scans are needed.
