I am developing a web-based medical imaging viewer using Trame-slicer. I used TotalSegmentator to generate anatomical masks and then load these .nii.gz files into the Slicer scene for 3D visualization.
Currently, I am loading each organ (Liver, Colon, Heart, etc.) from separate .nii.gz files into individual nodes. I suspect this overhead contributes to the performance degradation.
Merging Masks: Is there a recommended way to merge these multiple NIfTI files into a single vtkMRMLSegmentationNode with multiple segments upon loading? I want to reduce the number of Display Nodes and renderers that Slicer has to manage.
mask_files = [
"/trame_server3d/build/segment_result/colon.nii.gz",
"/trame_server3d/build/segment_result/liver.nii.gz",
"/trame_server3d/build/segment_result/heart.nii.gz",
"/trame_server3d/build/segment_result/kidney_cyst_left.nii.gz",
"/trame_server3d/build/segment_result/kidney_cyst_right.nii.gz",
"/trame_server3d/build/segment_result/kidney_right.nii.gz",
"/trame_server3d/build/segment_result/kidney_left.nii.gz",
# Add more test paths here
]
segmentation_nodes = []
for mask_path in mask_files:
if Path(mask_path).exists():
logging.info(f"[ViewManager] Loading segmentation: {mask_path}")
# Because IOManager only handles one file at a time
node = self.slicer_app.io_manager.load_segmentation(mask_path)
if node:
segmentation_nodes.append(node)
After this, the loadSegment will using these nodes to display them:
```
def loadSegment(self, segmentation_nodes: list) -> None:
for node in segmentation_nodes:
seg_wrapper = Segmentation(
segmentation_node=node,
volume_node=self.volume_node,
editor_logic=self.slicer_app.segmentation_editor.editor_logic
)
seg_wrapper.enable_surface_representation()
Are there any options available here to explicitly choose between CPU or GPU rendering for segmentations, like in volume 3D render?
```
def createVolumeVisualization(self, volume_node, preset_name="CT-AAA"):
"""Setup Volume Rendering using Pure VTK Pipeline (CPU Only)."""
start_time = time.time()
self.volume_node = volume_node
# 1. Setup Volume Rendering Logic
vr_logic = self.slicer_app.volume_rendering._logic
renderOption = self.renderOption
if renderOption == RenderOption.CPU.value:
logging.info("[Volume] Rendering with CPU")
vr_logic.SetDefaultRenderingMethod("vtkMRMLCPURayCastVolumeRenderingDisplayNode")
elif renderOption == RenderOption.GPU.value:
logging.info("[Volume] Rendering with GPU")
vr_logic.SetDefaultRenderingMethod("vtkMRMLGPURayCastVolumeRenderingDisplayNode")
elif renderOption == RenderOption.MULTI_VOLUME.value:
vr_logic.SetDefaultRenderingMethod("vtkMRMLMultiVolumeRenderingDisplayNode")
self.slicer_app.display_manager.show_volume(
volume_node=volume_node,
vr_preset=preset_name,
do_reset_views=True
)
self.vr_display_node = self.slicer_app.volume_rendering.get_vr_display_node(volume_node)
self.view3D.render()
self.view3D.set_box_visible(False)
self.view3D.set_background_gradient_color([0, 0, 0], [0, 0, 0])
elapsed = time.time() - start_time
logging.info(f"[Volume] Volume ready after {elapsed:.4f} seconds")
In my current environment, I suspect that Trame-Slicer might be defaulting to GPU raycasting (or GPU-based Closed Surface representation) even on a machine that primarily supports CPU rendering, which causes significant lag (Even displaying only segmentation without showing 3D volume still causes lag).
Thank you for your help!