Best way to get a silhouette of a mesh?


Given a mesh in the top left, I would like a silhouette on the top right. I know I can use vtkCutter to get an outline created by intersection with a plane (bottom right). I tried vtkPolyDataSilhouette (bottom left), but I find it unsatisfactory - there are too many extraneous edges. Is there a way to improve it?

If this is for highlighting an actor then you can also use the outline glow rendering pass.

https://examples.vtk.org/site/Cxx/Rendering/OutlineGlowPass/

1 Like

It is not to highlight an actor. It is to draw the outline on a 2D image (e.g. 2D slice or an X-ray). I assume it is possible to read the frame buffer, and set up object, outline, and background colors to make it possible to extract the outline. However this seems like so much effort that cutter approach sounds very appealing.

You can also project the model to the slice plane (simple projection matrix). This will give you a filled model. If you need the outline of that then you can use some 2D image filtering.

2 Likes

I would like to have this in a stand-alone library, written in Python. Could you point me to the implementation of this feature in the code? I looked at vtkSlicerModelsLogic, vtkMRMLModelDisplayNode, and qMRMLModelDisplayNodeWidget, but I could not figure out where is the code to transform a mesh into a 2D image.

This is a display option, so it is implemented in the displayable manager of models. See the source code here for turning the transformation matrix that you would use for getting slice intersection to a matrix that provides slice projection.

1 Like

Thank you. This sounds reasonable. Make a projection matrix that way, then use PIL’s ImageDraw.polygon() to draw all the mesh’s triangles onto a 2D image, then binary erosion (from ITK, SciPy, or OpenCV) and subtraction to get the outline.

Yes, this should work. Probably rasterizing the polygons using VTK would be much faster than PIL. You can implement the image filtering using VTK, too, if you don’t want to use additional (and potentially slower) libraries.

1 Like

If you have the polygon already you can just create on outline by drawing the boundary edge directly without having to do a raster image erosion and subtraction to get the outline

There is not just one polygon but many of overlapping polygons, potentially millions.

The GPU can rasterize them in near-zero time even if there are millions, so it is a safe bet.

But it is true that you could also get the silhouette by computing the union of all the polygons. I don’t think there is a VTK filter for it, but you can use shapely or others. It would be interesting to see how much time it takes.

1 Like

That makes sense and I see why you recommend doing the heavy liftering in vtk as opposed to rasterizing possibly millions of polygons in Python with PIL, I was recently doing some compositing work with PIL and found it rather slow.

Maybe using the featureEdges filter of VTK with the boundaryEdges option on the planar projection of the mesh could help :slight_smile:

Hope it helps