How can I divide a segmentation by a plane or ROI?

Hello, I have airway segmentation that I would like to divide into regions (nasopharynx, oropharynx, hypopharynx) based on planes defined by the locations of points I have stored as fiducials. The airway segmentation is straightforward via thresholding, the fiducial placement is straightforward. I cannot figure out how to easily combine the two. If I could define a plane and use it to divide a segment into two segments, that would work. If I could define a rectangular prism ROI (like is used for CropVolume or Volume Rendering) and crop a segment down to that region, that would also work for me.

I understand that it would be possible for me to generate the ROI’s I want, crop the volume down to that ROI and then segment the cropped volume. However, I want to do this on multiple dynamic volumes (~40 time points each), and the extra processing time generating the cropped volumes seems unnecessary when it feels like I should be able to do the editing on the segmentations instead of the original volumes.

The scissors tool with rectangular selection area also seems close to what I want, but I don’t know how to operate the scissors tool from a python script (i.e. without interactive mouse selection of the area to keep), and as @lassoan pointed out in a different post, the scissors tool operates in display coordinates whereas the points I want to use to guide the cutting are in world coordinates.

The Surface Cut tool followed by Keep Selected Islands tool are also close to what I would want, except that again, they are hard to use from a script as they are designed to operate based on interactive mouse input.

If I could create a segment which filled an AnnotationROI, then I could use logical operators to generate what I want.

If there’s really nothing better, I’ll go with the Crop Volume approach, but it seems like Slicer probably has the capabilities I’m looking for, and I’m just not finding or putting them together in the best way.

Sounds like you might be able to use the amazing new Dynamic Modeler module

1 Like

I agree that this could be a nice application of Dynamic modeler, especially if you want to operate on models. If you prefer to remain in segmentation’s binary labelmap representation then you can use Surface Cut effect from a Python script as shown in its automated test:

1 Like

Thanks @pieper I’ll take a look at that.

So, I would:

  • take my segment, convert it to a model,
  • cut it with a plane cut and cap surface
  • convert cut model back to segment?

Thanks also @lassoan, I will also look at that method as well.

1 Like

Having looked at the two approaches, I think both are promising. I now understand the SurfaceCut tool much better than I did before. I initially assumed it had to do with cutting based on an existing model surface, or something like that. I now understand that you are interactively creating a model surface by placing points which should be on the surface of that model, and then using that surface to generate a segmentation. So, my thought after looking at the self test code for the SurfaceCut tool was to supply the 8 corners of the rectangular ROI I want to use to bound the airway segment volumes, and mask the intensity range to represent air, and fill inside. This would work perfectly if the SurfaceCut tool did not round the edges of the surface it generates. If I place 8 corners, the rounding means that voxels outside the box defined by those corners end up included inside the generated surface, when for my application they should be excluded because they are properly part of the next airway segment.

Is there any way to use the SurfaceCut machinery but use flat faces instead of smooth rounded surfaces? For my purposes the convex hull of the supplied points would be fine, I don’t need any concavity (which I see the curved surface doesn’t allow either). If not, I think I’ll have to go with the Dynamic Modeler approach.

You can change True to False in this line to turn off smoothing:

If you added a checkbox on the GUI to enable/disable smoothing and send a pull request then we would be happy to merge it.

1 Like

Great! I’ll work on doing that. I appreciate all the support! Thanks!

1 Like

Created pull request:

This is my first attempt making a pull request for a real github project. Thanks @lassoan for the encouragement to figure out the last few steps to contribute back to the Slicer community.

1 Like