You can copy-paste this code snippet to the Python console to show the anatomical angles (LAO/RAO, CRA/CAU) of the C-arm in the corner of a 3D view:
threeDViewIndex = 0 # change this to show angles in a different 3D view
def positionerAngleFromViewNormal(viewNormal):
# According to https://www5.informatik.uni-erlangen.de/Forschung/Publikationen/2014/Koch14-OVA.pdf
nx = -viewNormal[0] # L
ny = -viewNormal[1] # P
nz = viewNormal[2] # S
import math
if abs(ny) > 1e-6:
primaryAngleDeg = math.atan(-nx/ny) * 180.0 / math.pi
elif nx >= 0:
primaryAngleDeg = 90.0
else:
primaryAngleDeg = -90.0
secondaryAngleDeg = math.asin(nz) * 180.0 / math.pi
return [primaryAngleDeg, secondaryAngleDeg]
def formatPositionerAngle(positionerAngles):
primaryAngleDeg, secondaryAngleDeg = positionerAngles
text = f'{"RAO" if primaryAngleDeg < 0 else "LAO"} {abs(primaryAngleDeg):.1f}\n'
text += f'{"CRA" if secondaryAngleDeg < 0 else "CAU"} {abs(secondaryAngleDeg):.1f}'
return text
def cameraUpdated(cameraNode, view):
viewNormal = cameraNode.GetCamera().GetDirectionOfProjection()
positionerAngleText = formatPositionerAngle(positionerAngleFromViewNormal(viewNormal))
view.cornerAnnotation().SetText(vtk.vtkCornerAnnotation.UpperRight, positionerAngleText)
view.cornerAnnotation().GetTextProperty().SetColor(1,1,0) # yellow
view.scheduleRender()
layoutManager = slicer.app.layoutManager()
view = layoutManager.threeDWidget(threeDViewIndex).threeDView()
threeDViewNode = view.mrmlViewNode()
cameraNode = slicer.modules.cameras.logic().GetViewActiveCameraNode(threeDViewNode)
cameraObservation = cameraNode.AddObserver(vtk.vtkCommand.ModifiedEvent, lambda caller, event, view=view: cameraUpdated(caller, view))
cameraUpdated(cameraNode, view)
# Execute the next line to stop updating the positioner angles in the view corner
# cameraNode.RemoveObserver(cameraObservation)
We are developing a fluoro simulator module for interventional cardiology as part of the SlicerHeart project. The module will be able to display not just the angles but simulated fluoro images and compute optimal viewing angles, etc. We’ll release it when the results are first published - probably within a year.