vtkWindowedSincPolyDataFilter Smoothing - Processing Script

Hello,

I understand that vtkWindowedSincPolyDataFilter implements Taubin smoothing on closed surfaces. I am attempting to implement a script which achieves the following:
input: .nii file containing 3D segmentation labelmap [0,1,2] (3-label semantic segmentation)
output: .nii file containing 3D segmentation labelmap [0,1,2] after Taubin smoothing has been applied.

Could anyone suggest a sequence of vtk classes to utilize in order to achieve all the necessary type conversions? I attempted to follow 3DSlicer’s implementation- but it seems they used many Slicer-specific variables, making it difficult to translate to a script as I desire.

Kyle

First, check out the VTK examples, maybe this will help.

In Python: https://kitware.github.io/vtk-examples/site/Python/Medical/GenerateModelsFromLabels/
In C++: https://kitware.github.io/vtk-examples/site/Cxx/Medical/GenerateModelsFromLabels/

Second: send Andrew Maclean and all of the others who help put together this tremendous resource (VTK Examples) beer chits as an expression of thanks :slight_smile:

1 Like

Thank you very much for the example! I notice that the output of this script remains in a poly format. Do you have a suggested method for returning the output to a labelmap-type format?

edit: I came across https://kitware.github.io/vtk-examples/site/Python/PolyData/PolyDataToImageDataStencil/ will report back with if it achieves what I hope for :slight_smile:

@Kyle We are happy if 3D Slicer is useful for anyone, even if it is just for harvesting code from. But we would be even happier if developers could use Slicer features without dissecting and duplicating code, as it would make development and maintenance work much more efficient for everyone. Is there a specific reason why you cannot use Slicer’s implementation for this segmentation smoothing? Do you know that you can use Slicer without GUI (from the command-line, form Python scripts, or Jupyter notebooksl using local installation or docker)? Would you use Slicer features if you could pip-install them instead of having to run a classic desktop installer? Or you cannot install or use some Python packages in Slicer’s Python environment? Or you prefer to work with low-level VTK data objects instead of higher-level concepts (e.g., vtkImageData instead of vtkMRMLVolumeNode)? Or do you find the concepts (volumes, segmentations, segments, etc.) too complicated or not relevant for you (e.g., because you are not working with medical images)? Any piece of information would be useful for us so that we can evolve the software in a way that matches the needs of today’s medical image computing software developers.

Beer chits are always appreciated :grin:

Hello Dr. Lasso,

I first came across Taubin smoothing by testing out 3D Slicer’s smoothing methods. I liked the result of applying “Joint Smoothing” and followed the 3DSlicer code to find what smoothing was actually being utilized (vtkWindowedSincPolyDataFilter).

My use-case for Taubin smoothing is as a post-processing step on the output of a neural network which is a 3D semantic segmentation. The ML toolkit used also runs within a docker container. The inference pipeline I’ve created for the ML model all runs within this container, so all functions need to be self-contained there. Having the ability to use a tool like pip would be very useful in this case, as I wouldn’t have access to my system-installed Slicer.

I had a brief read through running python in non-slicer environment yesterday and tried to get it running on my local machine. It wasn’t immediately clear to me how I could reference 3DSlicer specific objects from commandline. For example, the smoothing code includes: segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
I assume that in a slicer runtime, this grabs the active segmentation node, but it wasn’t self-evident to me how I could apply this to an arbitrary labelmap.

@pieper @jcfr Is there a way to easily pull in Slicer into a docker container?

If you don’t use a GUI then you typically load the input data from files, something like these:

slicer.util.loadSegmentation("c:/tmp/tmp/Segmentation.nrrd")
slicer.util.loadSegmentation("c:/tmp/tmp/Segmentation.nii")
slicer.util.loadSegmentation("c:/tmp/Segment_1.stl")

You can find many more example in the Slicer Script Repository and if you are not sure how to do something then you can ask on the Slicer forum.

1 Like

This is what I do to install Slicer into my docker image:

Then once you have the image this is a recipe for running any Slicer python script, like the ones Andras linked from the script repository.

1 Like