Open valosekj opened 3 months ago
Hey @maxradx! I was able to save a segmentation with the same dimensions, resolution, and orientation as the source image. I recorded a short video documenting it.
Hi @valosekj ! Question of planning. Your short video corrects well the segmentation dimensions compared to the reference volume (now the dimensions fits). However, if we have 2 classes of segmentation (e.g. edema and hemorrhage), it saves it to one file (as shown in this image: white = presumed hemorrhage; grey = presumed edema). 1- That means it is not a binary file? 2- Is it better to have X files where X is the number of segmentation classes or is it better to have 1 file for all the segmentation classes as shown in this image?
1- That means it is not a binary file?
Each class seems to have its integer value, e.g., white: value 1
, gray: value 2
. You can verify this in FSLeyes by placing a cursor on a given region and checking the value in the bottom right corner. If this is the case, then it is fine!
2- Is it better to have X files where X is the number of segmentation classes or is it better to have 1 file for all the segmentation classes as shown in this image?
Good question! For the PRAXIS database, we currently have multiple files (i.e., one file each for SC seg, edema and hemorrhage). This convention is compatible with nnUNet training and also, for example, with the sct_analyze_lesion
function, which requires separate files for SC seg and lesion. However, splitting a multi-class file is easy (see example here), so if Slicer only supports saving a multi-class file, this is not a big problem.
Ok thanks @valosekj ! I implemented a new function and it works to convert the segmentation already done to the same format. However, the function does not work when it is from a new case (save with the wrong dimensions) and I don't know why .... Probably there is something uncorrect in the segments that are loaded (but technically, the function should register them in the same geometry).... Will look more in details this week!
Function example:
# Save segments with same dimensions as reference volume node
def save_same_dimensions(self):
self.enter_function("save_same_dimensions")
segmentation_node = self.get_segmentation_node()
volume_node = self.get_volume_node()
print("segmentation node name:", segmentation_node.GetName())
print("volume node name", volume_node.GetName())
# Get the active segment
segments = self.get_active_segments(segmentation_node)
# Iterate through segments and collect names
segment_names = self.get_segment_names_list(segments)
print("segment_names: ", segment_names)
# Create a label_map_volume_node
label_map_volume_node = slicer.mrmlScene.AddNewNodeByClass(
"vtkMRMLLabelMapVolumeNode")
slicer.modules.segmentations.logic().ExportAllSegmentsToLabelmapNode(
segmentation_node, label_map_volume_node,
slicer.vtkSegmentation.EXTENT_REFERENCE_GEOMETRY)
segment_ids = vtk.vtkStringArray()
for segment_name in segment_names:
print("segment_name: ", segment_name)
segment_id = segmentation_node.GetSegmentation(
).GetSegmentIdBySegmentName(
segment_name)
segment_ids.InsertNextValue(segment_id)
slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(
segmentation_node, segment_ids, label_map_volume_node,
volume_node)
# # Get the image data from the volume node
# image_data = label_map_volume_node.GetImageData()
#
# # Get the dimensions of the volume
# dimensions = image_data.GetDimensions()
# print(f"label map dimensions: {dimensions}")
# folder_path = (f"{self.output_folder}{os.sep}"
# f"versions{os.sep}")
folder_path = "/Users/maximebouthillier/gitmax/data_confid/test_conversion_tsci"
file_path = os.path.join(folder_path, segment_name)
slicer.util.saveNode(label_map_volume_node, file_path)
Basic question: why there is an issue when I paste the code in the block of code (like it does not copy paste it correctly ...) ?
I implemented a new function and it works to convert the segmentation already done to the same format. However, the function does not work when it is from a new case (save with the wrong dimensions) and I don't know why ....
Existing segmentations (annotated previously using FSLeyes or ITKsnap) already have the correct dimensions. Why? Because we created them as copies of the reference image (code here). The question is how 3D Slicer creates a new mask? Is it a copy of the reference image? (probably not; otherwise, dimensions would fit).
Basic question: why there is an issue when I paste the code in the block of code (like it does not copy paste it correctly ...) ?
I took the liberty to update your comment. To format text as a block of code, you can use backticks; see here.
I'm looking at sample segmentations for tSCI patients (PRAXIS) produced by @maxradx using 3D slicer, and I noticed that the label masks have different dimensions than the source image:
This is a problem. Ideally, the masks should have the same dimensions as the source image.