OK, I looked a little deeper into the ExtractCenterline.py code, and I think what you need is the vtkPolyData
for the closed surface representation of the segment.
segmentation = aorta_seg.GetSegmentation()
segmentID = segmentation.GetSegmentIDBySegmentName('Segment_1')
aorta_seg.CreateClosedSurfaceRepresentation() # just to ensure this representation exists
segmentVtkPolyData = vtk.vtkPolyData() # create empty vtkPolyData object
# Get vtkPolyData representation of segment surface into segmentVtkPolyData variable
aorta_seg.GetClosedSurfaceRepresentation(segmentID, segmentVtkPolyData)
For the rest of the details of how to use the VMTK centerline extraction from python inside Slicer, the best place to look is at the code from ExtractCenterline.py, available here: https://github.com/vmtk/SlicerExtension-VMTK/blob/3787ea4a300da28ec5f0824f0715f2713b631155/ExtractCenterline/ExtractCenterline.py
Some longer example code which might be helpful
In some old code, I found a method from inside a custom scripted Slicer module I had developed which uses the ExtractCenterline module’s logic.
def onGenerateCenterlineButtonClick(self):
"""Trying to mimic the implementation in ExtractCenterline.py from VMTK module"""
qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)
try:
## Gather inputs ##
linkedAirwaySegmentationNode = self._parameterNode.GetNodeReference(
"LinkedAirwaySegmentationNode"
)
linkedAirwaySegmentID = (
self.ui.linkedAirwaySegmentSelectorWidget.currentSegmentID()
)
endPointsMarkupsNode = self._parameterNode.GetNodeReference(
"EndpointsFiducialNode"
)
import ExtractCenterline
extractLogic = ExtractCenterline.ExtractCenterlineLogic()
## Preprocess ##
inputSurfacePolyData = extractLogic.polyDataFromNode(
linkedAirwaySegmentationNode, linkedAirwaySegmentID
)
if (
not inputSurfacePolyData
or inputSurfacePolyData.GetNumberOfPoints() == 0
):
raise ValueError("Valid input surface is required")
# These are the default values in the VMTK module, which I have never had to change (until I ran into an error)
# OK, now I've had to change decimationAggressiveness down to 3.5 from 4.0. Preprocessed surface had inverted segments after decimation
# which lead to failed centerline curve. It is possible that we could detect failed curve if it has only two control points? (That was the
# case in the single failure so far). If so, we could re-run with lower decimation aggressiveness.
preprocessEnabled = True # (self._parameterNode.GetParameter("PreprocessInputSurface") == "true")
targetNumberOfPoints = 5000.0 # float(self._parameterNode.GetParameter("TargetNumberOfPoints"))
decimationAggressiveness = 3.5 # 4.0 #float(self._parameterNode.GetParameter("DecimationAggressiveness"))
subdivideInputSurface = False # (self._parameterNode.GetParameter("SubdivideInputSurface") == "true")
slicer.util.showStatusMessage(
"Preprocessing surface before centerline extraction..."
)
slicer.app.processEvents()
preprocessedPolyData = extractLogic.preprocess(
inputSurfacePolyData,
targetNumberOfPoints,
decimationAggressiveness,
subdivideInputSurface,
)
## Extract centerline ##
centerlineCurveNode = self._parameterNode.GetNodeReference(
"CenterlineCurveNode"
)
if centerlineCurveNode is None:
centerlineCurveNode = slicer.mrmlScene.AddNewNodeByClass(
"vtkMRMLMarkupsCurveNode", "Centerline curve"
)
slicer.util.showStatusMessage("Extracting centerline...")
slicer.app.processEvents() # force update
centerlinePolyData, voronoiDiagramPolyData = extractLogic.extractCenterline(
preprocessedPolyData, endPointsMarkupsNode
)
slicer.util.showStatusMessage(
"Generating curves and quantification results table..."
)
slicer.app.processEvents() # force update
centerlinePropertiesTableNode = None
extractLogic.createCurveTreeFromCenterline(
centerlinePolyData, centerlineCurveNode, centerlinePropertiesTableNode
)
if centerlineCurveNode.GetNumberOfControlPoints() == 2:
# Extraction had an error, likely due to too high decimation aggressiveness
# Try again
slicer.util.errorDisplay(
"Centerline generation failed, possibly due to decimationAggressiveness being too high."
)
# TODO TODO TODO: implement automatically trying again, with message to user about what's going on
except Exception as e:
slicer.util.errorDisplay("Failed to compute results: " + str(e))
import traceback
traceback.print_exc()
qt.QApplication.restoreOverrideCursor()
slicer.util.showStatusMessage("Centerline analysis complete.", 3000)
self._parameterNode.SetNodeReferenceID(
"CenterlineCurveNode", centerlineCurveNode.GetID()
)