Change spacing of segment using Python

Hi all,
I would like to specify the spacing of a segment i am creating using python.

Manually, I can do so using “specify geometry” as seen here Segmentations — 3D Slicer documentation
under " Editing a segmentation imported from model "

Can anyone let me know how to do it in python? here is my code to create a segment with default (1x1x1) voxel size but I want to change it to 0.004x0.004x0.004

Create segmentation

segmentationNode = slicer.mrmlScene.AddNewNodeByClass(“vtkMRMLSegmentationNode”)
segmentationNode.CreateDefaultDisplayNodes() # only needed for display
segmentationNode.SetName(‘Segmentation’)

Import the model into the segmentation node

slicer.modules.segmentations.logic().ImportModelToSegmentationNode(cylinderNode, segmentationNode)

You can set the geometry (origin, spacing, axis directions, and extens) of the binary labelmap segmentation as shown in this example in the script repository.

thank you for the reply but in that case I will have to allocate memory to each element which is huge in my case so it gives the error “Unable to allocate 242857881500 elements of size 1 bytes.”

is there a way to create the segmentation like I did before in the simple code and then modify its spacing?

This means that your reference image size would be 226GB. In general, I recommend to have 10x more RAM than your reference image size, which would mean that you would need 2260GB RAM and really, really fast processor to be able to do anything with this data.

These requirements are unrealistic to meet with today’s computing hardware, so I would recommend to reconsider your resolution needs or crop your data to a smaller region.

There might be also some misunderstanding about units. What is the distance unit of your model (meter, milllimeter, …)? What is the distance unit for 0.004?

it it 4 mico meters (0.004 millimeters)
on the GUI it is working fine which is why i am confused

What are the bounds (min/mix x, y, z coordinates) of the model that you are importing?

In the script example, an empty margin of 10mm is added around the model, which corresponds to about 5000 pixels along each axis. Probably you want to change it to something like outputVolumeMarginMm = 0.012.

I am importing an stl file of a cylinder that I created on 3dslicer
I wrote a code where i would draw a 2 points (markups) and then a cylinder of radius 3mm and height 3mm would be created and exported as an stl file but I did not specify any bounds i just specified the points on the GUI to assign the center and direction along these points. this is the code

cylinder = pyvista.Cylinder(center=center_cylinder, direction=cylinder_direction,
radius=cylinder_radius, height=cylinder_height)
cylinderNode = slicer.modules.models.logic().AddModel(cylinder)

slicer.util.exportNode(cylinderNode, parentpath / ‘segmented_volumes’ / side / cylinder_outputfile)

yes, reducing the volume margin worked like a charm! thanks

1 Like

One more thing,
later i am trying to combine 2 segments together using the following code:

segmentName = 'pores'

addedSegmentID = seg.GetSegmentation().AddEmptySegment(segmentName)
segmentEditorNode.SetSelectedSegmentID(addedSegmentID)


# Logical operators
segmentEditorWidget.setActiveEffectByName("Logical operators")
effect = segmentEditorWidget.activeEffect()


operation = "UNION"
segment_to_add = "void"

effect.setParameter("Operation", operation) # change the operation here
effect.setParameter("ModifierSegmentID", segment_to_add)
effect.self().onApply()

i am also getting the same error we discussed earlier “Unable to allocate 1711230150 elements of size 1 bytes.”

Do I have to specify the “VolumeMargin” somewhere here as well?

VolumeMargin is just used in your own code, it is not an effect parameter.

I suspect that the two segments are far from each other, which would make the combined segmentation too large.

I would recommend to work with lower resolution (larger spacing) during development to make everything work faster and let you see the results even if you make some small mistakes.