# Automatic centerline

**URL:** <https://discourse.slicer.org/t/automatic-centerline/14829>\
**Category:** VMTK\
**Created:** [December 1, 2020, 3:55pm UTC](https://discourse.slicer.org/t/automatic-centerline/14829 "2020-12-01T15:55:01Z")\
**Posts on this page:** 1\
**Showing post:** 23

<div class="post-metadata">

**Author:** ![mikebind](https://avatars.discourse-cdn.com/v4/letter/m/71e660/32.png) [@mikebind](https://discourse.slicer.org/u/mikebind)\
**Post date:** [October 28, 2021, 6:52pm UTC](https://discourse.slicer.org/t/automatic-centerline/14829/23 "2021-10-28T18:52:14Z")

</div>

It looks like the tests have not been updated since an earlier version of the module; the error message is correct that there is no run() method in ExtractCenterlineLogic. There is an extractCenterline() method which takes as inputs surfacePolyData, endPointsMarkupsNode, and a curveSamplingDistance. Here is what I think you need:

```auto
segmentationName = 'MySegmentationName' # replace with the name of your segmentation
segmentName = 'MySegmentName' # replace with the name of the segment you want to find the centerline of
segmentationNode = slicer.util.getNode(segmentationName)
segmentID = segmentationNode.GetSegmentation().GetSegmentIdBySegmentName(segmentName)

import ExtractCenterline
extractLogic = ExtractCenterline.ExtractCenterlineLogic()

# Preprocess the surface
inputSurfacePolyData = extractLogic.polyDataFromNode(segmentationNode, segmentID)
targetNumberOfPoints = 5000.0
decimationAggressiveness = 4 # I had to lower this to 3.5 in at least one case to get it to work, 4 is the default in the module
subdivideInputSurface = False
preprocessedPolyData = extractLogic.preprocess(inputSurfacePolyData, targetNumberOfPoints, decimationAggressiveness, subdivideInputSurface)

# Auto-detect the endpoints
endPointsMarkupsNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode", "Centerline endpoints")
networkPolyData = extractLogic.extractNetwork(preprocessedPolyData, endPointsMarkupsNode)
startPointPosition=None
endpointPositions = extractLogic.getEndPoints(networkPolyData, startPointPosition)
endPointsMarkupsNode.RemoveAllMarkups()
for position in endpointPositions:
  endPointsMarkupsNode.AddControlPoint(vtk.vtkVector3d(position))

# Extract the centerline
centerlineCurveNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsCurveNode", "Centerline curve")
centerlinePolyData, voronoiDiagramPolyData = extractLogic.extractCenterline(preprocessedPolyData, endPointsMarkupsNode)
centerlinePropertiesTableNode = None
extractLogic.createCurveTreeFromCenterline(centerlinePolyData, centerlineCurveNode, centerlinePropertiesTableNode)

```

After you run this, the centerline should be in `centerlineCurveNode`, and the auto-detected endpoints should be in `endPointsMarkupsNode`. I don’t know if the preprocessing step is strictly necessary (it seems like you may know more about the inner workings of VMTK than I do), but it seems recommended. To get this code snippet, I tried to pull the relevant lines out of a few functions in the ExtractCenterlineLogic class ([SlicerExtension-VMTK/ExtractCenterline.py at 3787ea4a300da28ec5f0824f0715f2713b631155 · vmtk/SlicerExtension-VMTK · GitHub](https://github.com/vmtk/SlicerExtension-VMTK/blob/3787ea4a300da28ec5f0824f0715f2713b631155/ExtractCenterline/ExtractCenterline.py#L378)). I have not tried running the auto-detect endpoints this way, but I have done the centerline extraction with supplied endpoints using VMTK using the above methods in one of my own python modules.

---

_[View the full topic](https://discourse.slicer.org/t/automatic-centerline/14829)._
