Python script to automate rotation

Hi all, I’m working on a project creating radiographic views from CT scans, rotating one volume inside another using the repository script (https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py). This works great. I need to make 1 degree increments and save time images each time, which for multiple patient samples, I’m hoping to automate. I wrote a Python script for exporting video and 3d spins of a CT volume for other projects, and that works well. Python and most programming is new to me but I can figure most stuff out with pointers in the right direction and google. In looking at the transform scripts that start to get into C++, I can’t really figure out whats going on though and could use some direction.

My workflow will be:

  1. use the Script linked above to set the rotation point for my volume.
  2. Increase the rotation by 1 degree.
  3. Capture screenshot.

In a python script, is there a way to change the rotation of a volume transform? Does anyone know any places to start looking around for ideas?

I’ve been looking at these scripts on the slicer github to try and figure out what’s going on with little progress:
Modules/Loadable/Transforms/qSlicerTransformsModuleWidget.h
Modules/Loadable/Transforms/qSlicerTransformsModule.cxx
Libs/MRML/Widgets/qMRMLTransformSliders.cxx
Libs/MRML/Widgets/qMRMLTransformSliders.h

Thanks for any suggestions!

Progress!

I found the qMRMLLinearTransformSliders pages by following the instructions for tracking down a slicer function, go figure :slight_smile:

Trial and error led me to:

increment = 1
transformNode = getNode('LinearTransform')
w = slicer.qMRMLLinearTransformSlider()
w.setMRMLTransformNode(transformNode)
w.TypeOfTransform = w.ROTATION_IS
w.applyTransformation(increment)

This is after using the repository script for rotation around a point. The ‘LinearTransform’ node is the transform that is adjusted with the transform sliders, and that is what I’m controlling with the script. You can adjust which slider by changing the TypeOfTransform line (Rotation or Translation, IS/LR/PA).

Now I need to write something simple to iterate through a range for the increment and take a picture each time.

Here is the final code for anyone interested.

First I load up the repository script for rotation around a point as linked above. Then I input my code below to setup the manual increment of the transform.

from slicer import qMRMLLinearTransformSlider

increment = 1
transformNode = getNode('LinearTransform')
w = slicer.qMRMLLinearTransformSlider()
w.setMRMLTransformNode(transformNode)
w.TypeOfTransform = w.ROTATION_IS
w.applyTransformation(increment)

To automate and export a high resolution image, I use the script from here.

Adjust the range, image resolution, and the output directory/filename structure as needed:

for x in range (0, 61):
    w.applyTransformation(increment)
    vtk.vtkGraphicsFactory()
    gf = vtk.vtkGraphicsFactory()
    gf.SetOffScreenOnlyMode(1)
    gf.SetUseMesaClasses(1)
    rw = vtk.vtkRenderWindow()
    rw.SetOffScreenRendering(1)
    ren = vtk.vtkRenderer()
    rw.SetSize(3000, 3000)

    lm = slicer.app.layoutManager()
    ren3d = lm.threeDWidget(0).threeDView().renderWindow().GetRenderers().GetItemAsObject(0)
    # actors = ren3d.GetActors()
    # for index in range(actors.GetNumberOfItems()):
    #    ren.AddActor(actors.GetItemAsObject(index))
    # lights = ren3d.GetLights()
    # for index in range(lights.GetNumberOfItems()):
    #    ren.AddLight(lights.GetItemAsObject(index))
    volumes = ren3d.GetVolumes()
    for index in range(volumes.GetNumberOfItems()):
        ren.AddVolume(volumes.GetItemAsObject(index))
    camera = ren3d.GetActiveCamera()
    ren.SetActiveCamera(camera)

    rw.AddRenderer(ren)
    rw.Render()

    wti = vtk.vtkWindowToImageFilter()
    wti.SetInput(rw)
    wti.Update()
    writer = vtk.vtkPNGWriter()
    writer.SetInputConnection(wti.GetOutputPort())
    writer.SetFileName("Out/%d.png" % (x-30))
    writer.Update()
    writer.Write()
    i = wti.GetOutput()
1 Like

worth noting that for rotation, 1 slider unit increment is equal to 1 degree change. I haven’t tried with translation but that may not be the case