Extracting co-ordinates of point cloud in a segmentation

I want to extract xyz co-ordinates of point cloud of a segment created in Slicer. I have tried saving a segment as a .ply file and then opened the same in Meshlab and saved it as a .xyz file to get the physical co-ordinates of all the points. That works. I wanted to know if there is a direct way to get the co-ordinates of points directly from 3D Slicer?

Yes, you can access the coordinates directly. For example, this code snippet gives you point coordinates in a numpy array:

segmentId = segmentationNode.GetSegmentation().GetNthSegmentID(0)
import vtk.util.numpy_support
pointData = segmentPolyData.GetPoints().GetData()
pointCoordinates = vtk.util.numpy_support.vtk_to_numpy(pointData)

Connectivity between points is very important, as often it is very difficult to accurately reconstruct a surface from just the point cloud. So, in general, I would recommend to export the full mesh (triangle cell point IDs as well), and not just points coordinates.

1 Like


Indeed, the API slightly changed since how it worked 5 years ago. GetClosedSurfaceInternalRepresentation returns what the segmentation node stores internally, which is for advanced use (because for example in the future one polydata may be used for multiple segments and you would need to extract mesh of a specific segment with an additional step). It is generally recommended to use GetClosedSurfaceRepresentation() method instead, because it will always return the mesh of the selected segment, regardless how internal implementation may change in the future.

Dear Andras,

Thanks for your guidance. What would be the second argument of GetClosedSurfaceRepresentation() in this example?

Also, I’m trying to fit a sphere to a point cloud.
Instead of creating 3-4 markup points, I prefer to use point clouds in order to enhance accuracy. If I use the SurfaceWrapSolidify extension, I can close the segment and get the outer point cloud. Does API has any function to get the external points and ignore the internal points?

Thnak you

It is a vtkPolyData object. See examples in the script repository.

You can use all the mesh points to fit a sphere. See a complete implementation in the script repository. The only change you need to make is to call slicer.util.arrayFromModelPoints() for an input model node instead of slicer.util.arrayFromMarkupsControlPoints() for an input markup node.

There is no need for any special API, as SurfaceWrapSolidify extension removes all internal points. If you find that after solidify operation only cells are removed but orphan points are still there then you can remove them using Surface toolbox module’s Clean option (or vtkCleanPolyData filter).

Thank you so much for your help. Fixed.