I have noticed a recuring problem when I try to use the Grow From Seeds method. I am trying to segment a hip articulation. For that, I tried Grow From Seeds constrained in a range of intensity. I placed the seeds on each bone and initialize. However, I often find leaks in the first results of segmentation, like such :
I tried to correct it by modifying the Seed Locality Factor, up to 10, but it doesn’t change.
I also use Watershed which usually leaks a bit less. But watershed can’t be constrained in a mask and tends to pick up the cartilage and create junctions between the models. Also I’m interested in segmenting only the cortical bone (hence the constrain on intensity range) which I can’t seem to do with watershed.
I know that I can modify the seeds over and over until I get the right result, but I was wondering if there is some way to improve the initial result for these kind of light leaks.
If anyone has a solution or a trick to help improve that workflow It would be helpful ! Thanks !
Yes, that’s a tricky structure to capture with Grow from Seeds.
Machine learning techniques are starting to work well for this class of problems. This tool might give an initial good result that could be refined (e.g. with Grow from Seeds) if you need higher resolution:
It seems that you are using the region obtained from thresholding as the seeds? If so that may have a drawback that the seeds are too close the to expected boundary.
As a general rule of thumb for the seeding location, I would put the seeds more or less at the “center” of the expected target. So when these seeds “grow out”, it has relatively equal chance in all directions.
If possible could you try this idea in placing the target seeds manually in the “center” of the target?
For the background seeds, usually, I would put in each 2D view a surrounding fence of them around the expected target. But not too close to the expected boundary too. Otherwise these seeds would “leak into the target” causing under-segment.
Propagation on the surface of another segment happens because there is no smoothing constraint in the grow-cut algorithm (in contrast, watershed and most neural networks have some inherent smoothing). Lack of smoothing means potential for very high accuracy and ability to represent arbitrarily complex shapes, but it also means that the results are more susceptible to noise and artifacts.
Most of the time you can remove this surface noise by applying smoothing after region growing, using Smoothing effect Median or Joint smoothing method.
This seems fascinating ! I tried the online version with an abdominal CT and the result is really interesting ! The details were kind of rough tho but as you say, by eroding the result I might use them as seeds for Grow From Seeds or Watershed. Do you know if there is a way to integrate this tool in a Python script in 3D Slicer to produce segments instead of individual nii.gz files?
Thank you very much for this link, it is really interesting !
Thank you for your feedback ! Yes, my seeds are from a thresholding based method. I try to generate seeds automatically and for now a threshold based method did the trick. I agree with the drawback you mention, I already eroded the seeds to drive them away from the expected boundary.
I tried the method you suggested, although as I mentionned, I’m interested in constraining the propagation to an editable area, so I don’t need a background.
I painted seeds with 3D brush more central to the segments, but the result is fairly the same :
Thank you prof Lasso for these informations. I thought that the seed locality factor in grow from seed would work similarily to the object scale in watershed. If I understand what you said, this doesn’t seem to be the case.
I tried a bit of smoothing and it helps a bit. Thank you ! The downside is that it’s a post-processing operation. Hence the Grow From Seeds needs to be applied first, losing the ability to adjust the seeds if smoothing is not enough… I need to see how I can incorporate smoothing operations in my workflow. Thank you for the tip !
Currently TotalSegmentator can be run independently from Slicer, but the results can be loaded and generally look very nice. Follow their directions on the github page and run the highest resolution model for best results. Use the flag, I think it’s --ml, to get a single .nii.gz file you can load as a segmentation. Yes it should be possible then to use this as input to Grow from Seeds. I’m not sure how it will do in the face of fractures or other pathology so please report back if you explore this path.
Ok so it can ONLY be run independantly if I understand well. Would be really nice to have a way to use it in Slicer via python scripting. I don’t really know how these thing work.
It does not solde the leaky grow from seeds issue but it is a really nice piece of information that I didn’t have ! Thank you !
We have included a TotalSegmentator option in the current version of Lung CT Segmenter (Lung CT Analyzer extension) within 3D Slicer. The setup is a bit tricky but should be automatic if you already got it going from the command line. You would have to use the “TotalSegmentator all” option on your even non-lung CT dataset and press “Start”. This will take several minutes.
and find all > 104 created segments - correctly named - in “Data”. Just check their “visibility”:
Having that call in “Lung CT Segmenter” only is probably not ideal. Maybe we should bundle all available pre-trained AI segmentation tools in a central extension …
Yes, this would be ideal as we have several tools that are already valuable to users. A challenge is that they all have a bit different requirements and interfaces. Plus the field is evolving quickly so by the time we integrate one thing another promising tool emerges. Also tasks that take more than a few minutes are often more convenient to use outside Slicer. Still, an nice high end tool for users could be developed.
TotalSegmentator deserves a separate Slicer extension, so I’ve added it now:
@rbumm you could use this TotalSegmentator extension from LungCTAnalyzer extension. If needed, we can refactor the module logic to allow you to do everything you need with just a few method calls.