Generate digitally reconstructed radiograph from 3DCT

Which dataset: training, validation, test?

VerSe 2020 > 03_test > verse 563.nii

I incorrectly said 629 in my last post. It is actually 563

Such misalignment is because of CT has internal matrix orientation.
Quick fix is to set matrix transform manually, by python script in python console.
The GUI fix will require a much more time.

mat = vtk.vtkMatrix4x4()
mat.SetElement(0, 0, -1.)
mat.SetElement(1, 1, -1.)
ct = slicer.mrmlScene.GetFirstNodeByClass('vtkMRMLScalarVolumeNode')
ct.SetIJKToRASMatrix(mat)

Thanks! That worked like a charm. Is there any reason why I shouldn’t use this for all CT volumes that I import into Slicer?

Will manually setting the matrix transform have any impact on the coordinates of Control Points in the Markup module?

I must be fixed within DRR module. Points should be OK, since points coordinates are transformed into world coordinates, but it must be checked.

Also try to use that transform to the ct volume. You can check original volume transform in “Volumes” module, “Volume Information” subsection.

mat = vtk.vtkMatrix4x4()
mat.SetElement(0, 0, -1.)
mat.SetElement(1, 1, -1.)
ct = slicer.mrmlScene.GetFirstNodeByClass('vtkMRMLScalarVolumeNode')
ct.SetIJKToRASDirectionMatrix(ct)

Is it possible to apply this to a new volume created from a CT? I created a smaller volume using the Crop Volume module on the transformed CT, but the DRR did not work on the cropped volume. The DRR was successful when I tried it on the transformed CT.

The misalignment is due to that Plastimatch’s DRR generation tool assumes an “LPS oriented volume”, i.e., an image with an IJK to LPS direction matrix like this:

[ spacingX      0         0      0 ]
[     0      spacingY     0      0 ]
[     0         0     spacingZ   0 ]
[     0         0         0      1 ]

but of course it is often not the case - image coordinate system axes can be arbitrarily rotated in space.

It should be straightforward to support arbitrarily oriented images. One simple solution is to compute a transform that transforms the image so that its IJK axes are oriented in LPS directions, then apply this transform both to the image and the camera position and orientation.

I will add support of oriented volumes later.

1 Like

Ideally this should be fixed upstream. (As well as using IEC to specify gantry angle, etc…)

In that case the ct volume orientation must be taken into account by the beam node, because beam node already use IEC Logic and angles to calculate beam orientation.

Hi Mik, Andras, and Greg,

I am still struggling with this. I can use the code that Mik shared:

to “correct” a CT volume such that the isocenter coordinates that I enter into the External Beam Planning module are in the center of a DRR created by the DRR Image Computation module. If I don’t apply the code snipped above, then the isocenter (and all patient anatomy) may be missing from the resulting DRR.

The reason that I still have a problem is that I need to create DRRs from cropped volumes created by the Crop Volume module. Cropping the original CT allows me to remove soft tissues that cause poor contrast in DRRs. The trouble is that the cropped volume isn’t “corrected” by the code snippet above. When I create a DRR from the cropped volume using isocenter coordinates that work on the un-cropped CT, there is no patient anatomy in the field of view.

Is there a quick fix that I could apply while this bug is sorted out?

@gcsharp I asked a question about this in the Plastimatch Google group last week. I have been alternating between Slicer and the Plastimatch Command prompt to figure out which is ideal for my use case.

You can apply a transform to the volume that preserves image spacing but rotates its axis to be aligned with LPS axes. You can find computation of a similar transform here:

Thank you for sharing this. What is the syntax for selecting a DataNode for this transformation?

When I copy the code above into Slicer’s the Python terminal, I receive a NameError code that the volumeNode is not identified. I’m not sure if the way that volumeNode is defined in NgffImageIO is relevant (line 345) .

I would like to apply it to “563_cropped” in the scene shown below. Generally, I would like to know how to apply it to any volume.

During debugging, you can get a node in the Python console like this:

volumeNode = getNode('563_cropped')

In a Slicer module you would use a node selector widget to let the user choose a node.

I was able to execute the code snippet with some modifications, but it did not solve my original problem.

Here is the code that ran:

import numpy as np
volumeNode = getNode('563_cropped')
spacing = volumeNode.GetSpacing()
ijkToRasMatrixVtk = vtk.vtkMatrix4x4()
volumeNode.GetIJKToRASMatrix(ijkToRasMatrixVtk)
ijkToRasMatrix = slicer.util.arrayFromVTKMatrix(ijkToRasMatrixVtk)
ijkToLpsMatrix = np.dot(ijkToRasMatrix, np.diag([-1.0, -1.0, 1.0, 1.0]))
xyzToIjkMatrix = np.diag([1.0/spacing[0], 1.0/spacing[1], 1.0/spacing[2], 1.0])
xyzToLpsMatrix = np.dot(ijkToLpsMatrix, xyzToIjkMatrix)

However, the isocenter that I selected in the External Beam Planning module was absent from a DRR calculated in the DRR Image Computation module. Here is a screenshot of the full view. Note the mismatch between the 3D rendering and the DRR in the 3D View.

Here is a screenshot of the resulting DRR.

How can I check that the transform was applied to 563_cropped? Is there anything else that could be causing this misalignment?

Thank you for all of your help!

Hi Mik, have you made any progress on adding support of oriented volumes?

Andras recommended a workaround that isn’t yet functional. See my last post.

Hi Andras, do you have any recommendations for determining whether the LPS transformation was applied to the cropped volume? See my reply to your post on 12/7.

I am not sure if my problem is there or if it is in the DRR Image Generation module.

Not yet.

In case of applying transform to cropped volume:

  • Create a transform node RAS->LPS (matrix you know) in Transforms module;
  • Apply a newly created transform node to cropped volume and markups that within the cropped volume;
  • After that you must harder the transform for the cropped volume and markups.
    That gives you a cropped volume orientated as default DICOM volume.
1 Like

That worked and solved all of my issues as far as I can tell! Thank you!

Minor question on DRR Image Generation module: How can I control the Plastimatch parameters vup (panel orientation)? I need to rotate the resulting DRR by 90 degrees.