Exporting Curvature Data

Hello everyone,

I am using the Slicer VMTK extension in order to extract centerlines from a vascular tree. In addition to radius, I would also like to have the curvature at every point of the centerline (like I would get from “vmtkcenterlinegeometry” command using VMTK alone).
So far I found that the markups module internally calculates the curvature of an extracted centerline curve (which it uses to find the curvature mean and max measurements and also to color the centerline when chosen as active scalar). Unfortunately I cannot find a way to export these values. Whichever way of saving I choose (e.g. as Markups JSON), it only contains curvature mean/curvature max and radius, but not a curvature value per point. Is there any way to export/save these values which slicer seemingly calculates internally already?

At the moment I am trying to look into the python interactor in order to try and get my hands on them, but as I am not familiar with the VTK framework I am having a hard time finding the measurement data.

Any help would be greatly appreciated!

No one has an idea for this?

I found out that I can access scalar data (the PedigreeIDs) of the markups curve using

res = slicer.util.arrayFromMarkupsCurveData(node, "PedigreeIDs")

but it does not work for curvature data:

res = slicer.util.arrayFromMarkupsCurveData(node, "Curvature")

always gives ValueError: Input markupsNode does not contain curve point data array ‘Curvature’. Available array names: ‘PedigreeIDs’

I do know the curvature values must be stored somewhere though, as I can use them as active scalar on display:

slicer_forum

Could anyone give me a hint on what to look into?

I was almost there…
Found out that I was missing one argument to get the Curvature data, which was setting the ‘world’ parameter to True:

res = slicer.util.arrayFromMarkupsCurveData(node, "Curvature", world=True)

Maybe someone else can profit from this knowledge. The question can be marked as solved.

Good to hear you were able to sort this out. I hadn’t used the feature myself but I see the documentation mentioned that flag. Maybe you didn’t have a chance to look or it wasn’t clear?

https://slicer.readthedocs.io/en/latest/developer_guide/slicer.html#slicer.util.arrayFromMarkupsCurveData

Curvature measurement is a dynamic measurement, computed only in world space, so it is not stored in the markup file. However, you can easily get the curve measurements from the markup node using arrayFromMarkupCurveData after you enabled curvature computation:

curveNode = getNode('OC')
curveNode.GetMeasurement('curvature mean').SetEnabled(True)
curvature = arrayFromMarkupsCurveData(curveNode, "Curvature", world=True)
plot(curvature)

image

Hi @heiko . I am trying to do the same thing – extract curvature data out of a coronary artery centerline network. I have two problems:
1) While I’m setting world = True, I still get the error message below

ValueError: Input markupsNode does not contain curve point data array 'Curvature'. Available array names: 'PedigreeIDs', 'Radius'

I’m using one of the many centerlines extracted. Could somebody point to a solution direction?
I followed Andras Lasso approach in the last post and it worked. However I only got 4-5 points of curvature. How can I control this, for example increase the points?

  1. Relevant to the last info, is there anyway to acquire the centerline as a whole, since I’m interested in studying it both segmented and not. I cannot seem to find the node that describes the centerline as a whole, all along the arterial tree.

You get as many points as points in the curve segment. If it is a very short segment then it may contain only 4-5 points. You can adjust sampling distance in Extract Centerline module / Advanced / Sampling distance.

You can get the entire centerline tree as a model (choose Extract Centerline module / Outputs / Centerline model) and compute the curvature using vtkvmtkCenterlineGeometry filter (see example here).

1 Like

Hi Andras, thanks for the quick reply.

  1. I managed to increase the points, but I do get a weird result. One of my curves has curvature values of over 100, even reaches 2000+ on a point. All other curves seem to have normal values. Is there any explanation/intuition for this? I am not very familiar with the curvature measurement procedure in general.

  2. I don’t exactly understand how to do this. Is there any tutorial to help get a hang of these python scripts on github describing the clasess and how can someone use them to construct code? For example, what I understand here is that I need to extract the centerline geometry from the model, but I cannot access the ExtractCenterlineLogic class to set compute geometry into “True”.

You need to use a smooth interpolation (e.g., spline) when resampling the curve. Otherwise you can have large values due to noise.

There are lots of tutorials online, but to get started, I would recommend the PerkLab Bootcamp Slicer programming tutorial.

Thanks a bunch for the tutorial, will definitely look into.

You need to use a smooth interpolation (e.g., spline) when resampling the curve. Otherwise you can have large values due to noise.

That means I need to resample to even more points than at the beginning right? I can find the option of distance in resampling (Centerline module : curve sampling distance mm) but not an option to select interpolator. Do I need to do this programmatically? Can you suggest the python method I should use to do it? I found that by using

getNode('curveNode').ResampleCurveWorld(n)

n describes the number of points of resampling.

For a smoother curve you need have less control points. If you less control points (or want more curve points sampled more densely along the curve) then you can call curveNode.SetNumberOfPointsPerInterpolatingSegment(20). This value specifies how many curve points are added between each pair of control points. Default value is 10, the higher the number the more dense the sampling is.

Hi,

I’m facing the same problem, so I tried this solution. The issue is that I want to calculate the curvature only at the centerline control points. How can I achieve that?

Hi @bserrano
If you set the number of points per interpolating segment to 1, then you basically get a curvature measurement for n=control points.
You can set the number of points per interpolating segment to 1 using:
curve_node.SetNumberOfPointsPerInterpolatingSegment(1)

To get number of control points per curve_node use:
curve_node.GetNumberOfControlPoints()

To get number of curvature points just measure length of curvature array:

curvature = arrayFromMarkupsCurveData(curve_node, "Curvature", world=True)
len(curvature)

I don’t know why you would want to do this though, because to get better curvature measurements you need a small number of control points and a large number of points per interpolating segment, at least that works for my case.
In general, I found it very useful to visualize the curvature values as mentioned in this post Separating centerline metrics - #9 by som1197

Thank you so much.

I think you are right because I’m getting a quite erratic curve

I see. To be honest, values are kind of ok - I sometimes get values of the thousands or something, which really don’t make sense! Maybe try and lower the number of control points & increase number of points per interpolating segment.

By the way, is that the centerline of a coronary artery? Curious because I’m working on such a project.

I’ll try. Many thanks.

Yes, it’s a coronary vessel.

Could you describe the process which you followed to get the centerline curve? Because I’m only able to get network curve on the coronary vessels I’m studying. I’m using CCTA scans as an input. My curvature centerlines produced are full of artifacts and straight lines.

Are you using the extract centerlines module? You can try the option “tree” instead of “network”. You need to be careful placing the control points and avoid sharpening geometries

Yes, I’m using both options. What happens is, while I’m getting an adequate representation on the network option, centerlines are completely off.
See: Centerline computation problem - straight lines

If you do have any suggestions it would be great!

Uhm, I think that the coronary segments are “too” smooth and too thin in some cases.
Which version of slicer are you using?