Script to add curve from control points

I have a dataset of thousands of scans that have already been landmarked. I now want to use a subset of existing landmarks to define new curves. This is quite straightforward to do manually by adding curves with the markups toolbox but I am stuck trying to script the same process (necessary because of the size of the dataset). It is possibly straightforward but I am a Slicer and Python novice. Below is a brief script of where I have got to so far. I can read the scan in and read in a csv containing coordinates for two control points defining the ends points of the curve. I can define the curve type (here, arbitrarily using a Kochanek spline). Next, I want to:

  1. include code to implement “Constrain to Model” from Curve Settings menu and constrain to the input model (shoebillNode)
  2. Resample the curve to e.g. 10 resampled points and set the output node to markupsNode1 from the script below.
  3. Output to file the resampled curve

I hope that makes sense. I would greatly appreciate suggestions on how to script this. At this point I am not even sure which functions I need.
Many thanks
Gavin

# Read obj model
shoebillNode = slicer.util.loadModel('Balaeniceps_rex_2.obj')

# Read markups with two points
markupsNode1 = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsCurveNode")
slicer.modules.markups.logic().ImportControlPointsFromCSV(markupsNode1, 'Table1.csv')

# Input control points (not sure if this is necessary - does it do anything different to the previous two lines?)
slicer.vtkProjectMarkupsCurvePointsFilter().SetInputCurveNode(markupsNode1)

# Kochanek spline
slicer.vtkMRMLMarkupsCurveNode.SetCurveTypeToKochanekSpline(markupsNode1)

You can do this:

markupsNode1.SetAndObserveSurfaceConstraintNode(shoebillNode)

You specify not the number of control points but instead the distance between them:

markupsNode1.ResampleCurveWorld(15.0)

The simplest and most rich export is to json:

slicer.util.exportNode(markupsNode1, "c:/tmp/mycurve.mrk.json")

I would not recommend to export point coordinates into CSV, because you would lose all metadata, but if you want to do it anyway then you can export the points to a numpy array:

import numpy
a = slicer.util.arrayFromMarkupsControlPoints(markupsNode1)
numpy.savetxt("c:/tmp/mycurve.csv", a, delimiter=",")
1 Like

Thank you - that is exactly what I was looking for.

1 Like