Distance (height) between two landmarks

Hello, I am new to 3D Slicer. sorry if this question was asked before.
I have transform the volume (inside the original ORI) to align with the Frankfurt plane. I want to calculate distances between landmarks, and I can get he direct distance via 1. right click on two landmarks, 2. export to excel and calculate (in R) with the Euclidean formula.
Now I would like to get the height between the points (in the figure here: the distance between the two white dots of the ORI) … how can I get the reference to the axis? is there an easy way to get this value?


Thank you in advance, Einat

You can get the size of the ROI by typing this into the Python console:

getNode('Volume rendering ROI').GetSize()

You can write a few-line Python script that collects all measurements from the scene and writes it into a CSV file that you can load into Excel. I would recommend the PerkLab bootcamp Slicer programming tutorial to get started If you need help then you can always ask us here.

Thank you Andras. I typed the python code and received the following:
image
what is the difference between these coordinates to those in the Control Point section?
Einat
** I’ve figure it!
the code gives the actual size in mm of each ROI face and the Control Point is the location of the ROI middle point
I’ll go to the tutorial to learn more,
Thank you.

1 Like

There is one control point, in the center of the ROI. You can get coordinates of the bounding box corners by adding/subtracting half of the ROI size to the center point coordinates.

1 Like

I was trying to run the code from the python Interactor directly to get the data I need from one of my samples. So instead of coping the Pre-populate the scene with measurements code I added a line to define lineNode:

lineNode=[‘Sinuses_LM_template’, ‘Skull_LM_template’, ‘Volume rendering ROI’]
but I got: Copied 0 length measurements to the clipboard
so I added dummy length measurement ‘L’, cause I thought maybe the code fits only for ‘lengths’, but still I got the same message.
Is there any way I can use this code to retrieve the landmark set ?
image
image

The code looks about OK (other than the lineNode list is unnecessary) but I cannot have a closer look because the code is in a screenshot. Could you please copy the code here as text?

Hi,
this is the code:

lineNode=['Sinuses_LM_template', 'Skull_LM_template', 'Volume rendering ROI','L']
def copyLineMeasurementsToClipboard():
  measurements = []
  # Collect all line measurements from the scene
  lineNodes = getNodesByClass('vtkMRMLMarkupsLineNode')
  for lineNode in lineNodes:
    # Get node filename that the length was measured on
    try:
      volumeNode = slicer.mrmlScene.GetNodeByID(lineNode.GetNthControlPointAssociatedNodeID(0))
      imagePath = volumeNode.GetStorageNode().GetFileName()
    except:
      imagePath = ''
    # Get line node n
    measurementName = lineNode.GetName()
    # Get length measurement
    lineNode.GetMeasurement('length').SetEnabled(True)
    length = str(lineNode.GetMeasurement('length').GetValue())
    # Add fields to results
    measurements.append('\t'.join([imagePath, measurementName, length]))
  # Copy all measurements to clipboard (to be pasted into Excel)
  slicer.app.clipboard().setText("\n".join(measurements))
  slicer.util.delayDisplay(f"Copied {len(measurements)} length measurements to the clipboard.")

shortcut2 = qt.QShortcut(slicer.util.mainWindow())
shortcut2.setKey(qt.QKeySequence("Ctrl+Shift+m"))
shortcut2.connect( 'activated()', copyLineMeasurementsToClipboard)

f = open("demofile2.txt", "a")
f.write(lineNode)
f.close()

You can create a set of line nodes with predefined names with a keyboard shortcut (Ctrl+Shift+N):

def addLineNodes():
  lineNodeNames = ['Sinuses_LM_template', 'Skull_LM_template', 'Volume rendering ROI', 'L']
  for lineNodeName in lineNodeNames:
    slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsLineNode", lineNodeName)

shortcut1 = qt.QShortcut(slicer.util.mainWindow())
shortcut1.setKey(qt.QKeySequence("Ctrl+Shift+n"))
shortcut1.connect( 'activated()', addLineNodes)

Once the line are added, you can go to Markups module, select one, then activate place mode on the toolbar to place the endpoint of that line.

Once your added all the measurements, you can add the results to a file with a keyboard shortcut (Ctrl+Shift+M):

def copyLineMeasurementsToClipboard():
  measurements = []
  # Collect all line measurements from the scene
  lineNodes = getNodesByClass('vtkMRMLMarkupsLineNode')
  for lineNode in lineNodes:
    if lineNode.GetNumberOfDefinedControlPoints() < 2:
      # incomplete line, skip it
      continue
    # Get node filename that the length was measured on
    try:
      volumeNode = slicer.mrmlScene.GetNodeByID(lineNode.GetNthControlPointAssociatedNodeID(0))
      imagePath = volumeNode.GetStorageNode().GetFileName()
    except:
      imagePath = ''
    # Get line node n
    measurementName = lineNode.GetName()
    # Get length measurement
    lineNode.GetMeasurement('length').SetEnabled(True)
    length = str(lineNode.GetMeasurement('length').GetValue())
    # Add fields to results
    measurements.append('\t'.join([imagePath, measurementName, length]))
  # Add all measurements to file
  with open("c:/tmp/demofile2.csv", "a") as f:
    f.write("\n".join(measurements) + "\n")
  slicer.util.delayDisplay(f"Copied {len(measurements)} length measurements to the clipboard.")

shortcut2 = qt.QShortcut(slicer.util.mainWindow())
shortcut2.setKey(qt.QKeySequence("Ctrl+Shift+m"))
shortcut2.connect( 'activated()', copyLineMeasurementsToClipboard)