Resampled segmentation limited by a bounding box (not the whole volume)

Operating system: Mac OS Catalina 10.15.7
Slicer version: 4.13.0-2021-04-04 (also 4.11)
Expected behavior: Able to perform segmentation using a resampled version on the whole volume
Actual behavior: Segmentation using a resampled version is limited to a bounding box

Hello Slicer community, this is my first post on this forum,

I could not find the answer in this forum, please redirect me if this has been already answered.

I resampled pairs of volumes and segmentations so that I can perform random re sizing of segmentation labels. Among my dataset I have variable slice thicknesses which limits my ability to use the grow/shrink segmentation module (I want to increment by 1 mm steps). Segmentations were performed using the original head CT images without resampling prior to segmentation. The typical resolution of original images is 0.5 x 0.5 x 4.0 mm and I resampled this to 1.0 mm3 isotropic voxels. I was able to do this using the following script as well as using the torchio package (tio.resample) .

Load any volume and perform a sample segmentation

Get nodes

volumeNode = slicer.util.getNode("vtkMRMLScalarVolumeNode1")
segmentationNode = slicer.util.getNode("vtkMRMLSegmentationNode1")

Resample the volume

transformedVolumeNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode")
parameters = {
    "outputPixelSpacing":"1,1,1",
    "InputVolume":volumeNode.GetID(),
    "interpolationMode":'linear',
    "referenceVolume": volumeNode.GetID(),
    "OutputVolume":transformedVolumeNode.GetID()}
slicer.cli.run(slicer.modules.resamplescalarvolume, None, parameters)

Resample the segmentation

transformedSegmNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
parameters = {
    "outputPixelSpacing":"1,1,1",
    "InputVolume":segmentationNode.GetID(),
    "interpolationMode":'linear',
    "referenceVolume": segmentationNode.GetID(), # I also tried volumeNode.GetID()
    "OutputVolume":transformedSegmNode.GetID()}
slicer.cli.run(slicer.modules.resamplescalarvolume, None, parameters)

However, when I try to perform additional annotations on the resampled segmentation I am limited to a smaller ROI than the volume (I can segment a bounding box that seems to be limited by the outer edges of the original segmentation). This occurs using resampled segmentations from both Slicer and torchio. Interestingly using itk-snap I can edit segmentation over the whole resampled volume, as expected (but not in Slicer).

I am able to recreate this issue using a downloaded sample image from Slicer after performing a segmentation, then running the script above and trying to annotate the resampled pair of volume/labels.

If there is a way to correct this using python scripting I’d be very interested in getting the code since I want to leverage the ability to batch process multiple cases using the Jupiter integration.

Maybe I am doing something wrong, please let me know,

Thanks

Best,

Laurent

Segmentation geometry (origin, spacing, axis directions, extents) is determined from the first selected master volume, as described here. You can change the geometry later, if necessary, but you can avoid this by resampling the volume before segmentation.

When you import a data set with varying spacing, Slicer computes a non-linear transform, which moves all the slices to the correct physical location and interpolates across the varying distances. I think segmentation module can work on volumes that are under a non-linear transform, but I haven’t checked this now, so if you run into any problems then you can harden the transform on the volume before you start the segmentation. You can do that in Data module: right-click on the transform column of the volume node, and harden the transform (resample the volume). You can of course do this from Python, too (by calling ApplyTransform. If there is any specific geometry (extent, spacing, etc.) that you want then you can use a resampling module or Crop volume module to resample the volume.

1 Like

Thank you for the answer.

The missing part in the last code block was, as suggested, to set the reference geometry. Here is the code to resample a segment and set its reference geometry.

Resample the segmentation (corrected)

# Create a resampled node
transformedSegmNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
parameters = {
    "outputPixelSpacing":"1,1,1",
    "InputVolume":segmentationNode.GetID(),
    "interpolationType":'linear',
    "referenceVolume": transformedVolumeNode.GetID(),
    "OutputVolume":transformedSegmNode.GetID()}
slicer.cli.run(slicer.modules.resamplescalarvolume, None, parameters)

#Set reference geometry (resampled volume)
transformedSegmNode.SetReferenceImageGeometryParameterFromVolumeNode(transformedVolumeNode)