How can we pass a line through two mark up fiducials ?
Or even three of them. Like making an axis to join them.
If you have two points in a markups fiducial node ‘F’, you can create a new markups line node using the snippet:
F=getNode('F')
L=slicer.mrmlScene.AddNewNodeByClass('vtkMRMLMarkupsLineNode')
firstPoint = F.GetNthControlPointPositionVector(0)
L.AddControlPoint(firstPoint)
secondPoint = F.GetNthControlPointPositionVector(1)
L.AddControlPoint(secondPoint)
A line will only work with two points, if you have more than that you would need to use a markups curve node.
Hi @smrolfe,
I was wondering how to modify the code snippet if my landmarks (control points) are in different markups fiducial nodes. How can I just specify the names of my control points that would be the endpoints of my linear distances?
Do you know the index of the control point in each node? If so, you can use the same method but select the second control point from a different node.
If you need to do this by control point name, you can loop through the points in each node, use c1.GetNthControlPointLabel()
to get the point name, and match to the name you are looking for.
Thank you for the quick reply @smrolfe !
I am quite unfamiliar with python scripting - can you point me to a guide on how to apply the c1.GetNthControlPointLabel() function?
I tried replacing the initial code with your suggestion like this:
L=slicer.mrmlScene.AddNewNodeByClass('vtkMRMLMarkupsLineNode') firstPoint = c1.GetNthControlPointLabel('praR') L.AddControlPoint(firstPoint) secondPoint = c1.GetNthControlPointLabel('paR') L.AddControlPoint(secondPoint)
However, I keep getting the error message: NameError: name ‘c1’ is not defined
My goal with this would be that the linear measurements are defined by their name and not the position and each time I can run the script after I placed the landmarks by hand e.g I have my endpoints as node names (e.g. prn-porion, se-sellion) and would like to compute the lines using the node names (e.g. prn-se).
I would also like to name the newly generated line in the script (e.g. ear width R).
If you are collecting landmark points, I strongly recommend that you use the same order every time, i.e. “prn-porion” has the same landmark number for each subject. If some subjects are missing points, these can be included with the position set to missing. Please see our tutorials on the control point position status and landmark template creation for more information.
For two point lists, named “F” and “G”, the following snippet will create a line measurement between landmark 0 in each list and name the line “myMeasurement”. To run, replace “F” and “G” with your point list names and “0” with the point number of the landmark in each list.
F=getNode('F')
G=getNode('G')
L=slicer.mrmlScene.AddNewNodeByClass('vtkMRMLMarkupsLineNode')
firstPoint = F.GetNthControlPointPositionVector(0)
L.AddControlPoint(firstPoint)
secondPoint = G.GetNthControlPointPositionVector(0)
L.AddControlPoint(secondPoint)
L.SetName("myMeasurement")
For the example above, replace c1
with F
. The function GetNthControlPointLabel()
takes an integer point number and returns a string with the point name. So to check the name at point 0, you can use:
labelName = F.GetNthControlPointLabel(0)
You can also find a control point by label. I’ve just tried and bing chat provides a perfect answer:
I’ll add a GetControlPointIndexByLabel()
method to markups node to be able to find a control point by a simple call.
Thank you @lassoan!
I realise it is a quite simple question, thank you for taking the time to answer it. My Bing search was less successful (although having asked the same question) - would you mind providing me with the full code you got?
A post was split to a new topic: How to set colors of markups?