Help with orientation marker and ruler

Hello,
I need help with the following.

  1. Is there a line of Python code that I can add to my scripted module to make the Axes Orientation Marker show up on the red and yellow slices automatically, without navigating to the “Show Orientation Marker” menu for the red & yellow slices?

  2. What tools can I use to measure objects in an image other than this one? Something that allows the user to get more precise measurement of things like tumor diameter would be great.


    Please note that I want the user to be able to use the ruler while still having my scripted module selected. I don’t want the user switching back and forth between a “Measurement” module and my module in order to make a tumor diameter measurement. Is there any ruler option other than the one shown in my screenshot that is not a separate module?
    Thanks,
    Rohan Nadkarni

Orientation markers can be configured by adjusting properties of the corresponding view node. For example:

viewNode = getNode('vtkMRMLSliceNodeRed')
viewNode.SetOrientationMarkerType(viewNode.OrientationMarkerTypeHuman)

For manual diameter measurements, you can use markup line.

For automated measurements, you can segment the tumor using one of the semi-automatic or fully automatic methods in Segment Editor, then use Segment Statistics to compute its parameters (volume, largest diameter, smallest diameter, sphericity, surface area, mean/min/max intensity etc.).

I would recommend to add a qSlicerSimpleMarkupsWidget to your module GUI. It allows you to create a new markups (the type(s) you specify), rename, delete, start/stop placement, edit control points, show/hide, jump to points, etc.

You can see results in your module by adding a qMRMLSubjectHierarchyTreeView to your module widget.

To view/edit/copy/save quantification results, you can also add a qMRMLTableView. It can display the content of a table node. Table node is stored as a .csv file.

Thanks. I got the orientation marker part. Is there a good Slicer python code example for me to look at for the Markups Widget and Hierarchy Tree View?

Hello again,
I spoke to the people who will be the end users of my Slicer module and they really do want something more precise than the built-in ruler tool I referred to in the first post in this thread.
If you have any links to share that could help me figure out the syntax for adding a ruler tool to my module (using qSlicerSimpleMarkupsWidget?) that would be greatly appreciated.

The new markups line tool is as accurate as it gets, with manual point placement. You can zoom in the image as much as you need and you can also set shape, size, opacity, thickness of markups control point marker and line to maximize visibility:

You can refine the position of a markup point in 3D by clicking on it (which it jumps to that slice in all views) and then adjust the position any any of the views.

Great. Is there an easy way to add this feature to my own scripted module, or would I have to switch to the markups module?

Of course, you can do this in your own module. All these properties are defined in the markups node’s display node. You can also set parameters that you like and click “Save to defaults” button in Markups module / Display section, to use those values as default for new markups.

Would you be able to share any example code for how to add and use a markups line tool as part of a scripted module?
Preferably something that’s compatible with Slicer 4.11.0, but I’m open to hearing about newer features too.

You can find many examples in script repository. If you have trouble finding an example for a specific task then let us know.

1 Like

Thanks for the link.
I added the code from this link

directly to my module.

However, no matter where I place the two fiducials, I always get a distance of 0 between them, as you can see here.

Is there something wrong with how I’m placing the fiducials?
Alternatively, how can I make minor changes to this code so that I’m calculating the length of a line chosen from the “Create and Place” instead of distance between 2 fiducials?

Thanks,
Rohan Nadkarni

The module was developed for an earlier version of Slicer and markups have been greatly improved since then and the API has change, too.

You can now use Markups ruler and curves to measure distances, so this custom module should not be necessary anymore.

Is there a script repository example using the markups ruler?

Sorry to have so many follow-up questions about this.

You can get length of markups line and curve like this:

print(getNode('L').GetLineLengthWorld())
print(getNode('C').GetCurveLengthWorld())

Sounds good, thanks.
But does this command have some compatibility issue with Slicer 4.11.0?
I’m getting:

print(getNode('L').GetLineLengthWorld())

AttributeError: 'vtkSlicerMarkupsModuleMRMLPython.vtkMRMLMarkupsLin' object has no attribute 'GetLineLengthWorld'

Use the most recent stable (Slicer-4.11.20200930).

1 Like

Unfortunately, it’s not working in the most recent stable either.
The curve length command works fine but the line length one doesn’t.

Is there any sort of work-around where I could save the line’s description to a string and get the length from there?

I can confirm that does work with the latest stable (Slicer-4.11.20200930). Copy-paste this code into the Python console and let me know what you see (you should see a line showing up in the viewers and “50.0” printed on the console.

lineNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsLineNode")
lineNode.AddControlPointWorld(vtk.vtkVector3d(0,0,0))
lineNode.AddControlPointWorld(vtk.vtkVector3d(30,40,0))
print(lineNode.GetLineLengthWorld())

You’re right, I mistakenly opened the earlier version of Slicer without realizing it.
It works in the latest stable release for me too.

Thank you so much for all your help with this task.

1 Like

@lassoan,

Could you direct me to Python scripting that will allow user interactive measurement by moving and adjusting the line length?

Thanks

@lasson

Wait! That example does do exactly that. And it’s very nice!!! So, all I need now is to be able to manually draw a line on a any of the 3 orthogonal planes and have them reflected in the 3D graphics. How do I enable the user to draw the line?