Segmentation Performance Optimization
Closed this issue · 5 comments
When there are hundreds of drawn segments, the performance of various operations (slice browsing, editing, saving/loading, etc) can become increasingly slow.
To support a large number of simultaneously displayed segments, we need to find an approach that can support these types of segmentations.
Approach: Merged Labelmap
If segments are not allowed to overlap, they can be stored as a single merged labelmap
When editing:
- If segment can overlap
- Segment copied into own labelmap if not already
- If segment cannot overlap
- Segment copied into merged labelmap if it is not already
When saving:
- Check to see if non overlapping segments can be safely merged
- If segment's don't overlap, then merge to a single labelmap representation
What to do about vtkSegment::GetRepresentation()?
- Return pointer to thresholded version of the merged labelmap and synchronize changes between thresholded labelmap and orginal merged labelmap as long as the pointer is alive?
@lassoan What level should the value of a segment in the merged labelmap be recorded at?
vtkSegment generally has no awareness of the representation types it contains, but that would be the most logical place to put it, so that vtkSegment::GetRepresentation() could return the thresholded labelmap for only that segment.
Yes, it would need to be stored at the vtkSegment level. You can add a class member variable (not a custom tag).
Update regarding the implementation of merged label-map handling:
Merged labelmap visualization, editing and saving are all mostly complete, and has much better performance in important aspects in segmentations containing a large number of segments, such as the NAC brain atlas:
- Faster rendering
- Faster editing
- Faster saving and smaller files
Current implementation can be found here: https://github.com/Sunderlandkyl/Slicer/tree/merged_segments
Result of discussion regarding the usage and handling of merged labelmaps:
-
Ensure that higher levels of methods provide easy access to relevant data
- GetBinaryLabelmapRepresentation() should return a thresholded labelmap with only the single segment
- If users want to edit the segment, they should use the methods in the segment editor classes to modify the original merged segment lablemap
-
Segment conversion rule base class should be modified to contain a Pre+Post processing step that can be performed on the Segmentation as a whole, rather than on the individual vtkDataObject.
Ex. For closed surface conversion:- PreConvert: Perform the actual conversion of the merged labelmap to a single vtkPolyData
- Convert: Separate the individual segments into their own vtkPolyData
- PostConvert: Do nothing (potentially other conversion rules might need this step)
The Segmentation performance optimization has been implemented and is being reviewed here: Slicer/Slicer#1221
By using a single merged labelmap instead of many separate segments, there should be a massive performance increase when editing and viewing atlases in Slicer with hundreds of segments.
From a user perspective, virtually nothing should have changed (except for the performance increase).
Using "Allow overlap" when editing segments, will drop performance to the original level, however if most editing is done with "Overwrite all", then it should be much faster.