Cylinder fitting

I have a segmentation that has a cylindical shape but is uneven and has different radii throughout. I would like to calculate the radius at different intervals to find the largest and smallest radius. Then fit a cylinder to that segmentation that has that radius and the correct angle. How could I achieve this? Thanks

You can use Segment Statistics module to get:

  • center of gravity: on point along the cylinder axis
  • principal axis: direction of the cylinder axis
  • volume: you can use this value along with the length of the cylinder (from oriented bounding box size) to get the average radius of the cylinder

Alternatively, you can use VMTK extension to get all the cylinder axis points and radius values along the axis.

If you know the expected cylinder length and radius then you can also use Model Registration or Segment Registration modules (provided by extensions).

2 Likes

Great, thank you for your help. I am still struggling with how to find the length can you explain this a bit more?

Also, I am still not clear on how to generate a cylinder that fits my segmentation. Can I do this using the General Registration module?

Length is provided by the orientation d bounding box size.

You can use a model node to display the cylinder. Set the output of a vtkCylinderSource as input polydata of the model. See many of examples in the script repository: Script repository — 3D Slicer documentation

I am having trouble using the python code to generate the bounding box. Its is giving me an error AttributeError: ‘MRMLCorePython.vtkMRMLLabelMapVolumeDisplayNode’ object has no attribute ‘GetVisibleSegmentIDs’

Is there a way to fix this or generate bounding box manually?

The error is given for the code, segStatLogic.computeStatistics()

Under what header in the script repository would an example of generating a cylinder be? I cant locate it

Segment Statistics module requires segmentation input. You can load a binary volume as segmentation; or load it as labelmap and then convert it to segmentation.

There are a number of relevant examples in the Models section. For example this one.

Thank you for your help it is much appreciated.

I tried out the code:
implant = vtk.vtkCylinderSource()
implant.SetHeight(100)
implant.SetRadius(8)
implant.SetCenter(-78.778,102.725,-181.217)
implant.SetResolution(100)

implantNode = slicer.modules.models.logic().AddModel(implant.GetOutputPort())
implantNode.GetDisplayNode().SetColor(0,0,1)
implantNode.GetDisplayNode().SetOpacity(1)

I used some of the values I obtained from segment statistics. However, I am trying to automate this process. Is there a way that I can use variables to input for the radius and height instead of values?

I am also having trouble with some of the values. Is their a variable that contains the length? And how do I find the angle of rotation so that the cylinder is in the same direction?

The segment statistics gives me the ferret diameter which is not the correct diameter of my segmentation.

I tried using VMTK to extract centerline however it only gives me one value for the radius. How do I get multiple values along the length of the segmentation as displayed in the example picture? Thank you!

pic1

pic2

‘Cross-section analysis’ module should fulfil this part of your needs. You can get diameters at each centerline point in a table, and plot them in a graph.

I am not sure what I am doing wrong but I can not figure out how to get my segmentation(1st pic) to look like the 2nd with all the centerline points along the line. I tried using cross section analysis but cannot get it to work.

Is their a step i need to do between creating the centerline and using the cross section analysis tool?

You are showing a centerline model in the first image. 'Extract centerline allows to generate a centerline curve too (second image). 'Cross-section analysis ’ works with both centerline models and curves. Prefer the curve variant as the centerline model is, though not really so, but nearly legacy.