# Generate digitally reconstructed radiograph from 3DCT

**URL:** <https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010>\
**Category:** Support\
**Created:** [February 2, 2018, 2:56pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010 "2018-02-02T14:56:19Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![Mik](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@Mik](https://discourse.slicer.org/u/Mik)\
**Post date:** [November 29, 2022, 3:03pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/22 "2022-11-29T15:03:55Z")

</div>

Which dataset: training, validation, test?

---

<div class="post-metadata">

**Author:** ![fieldr4](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@fieldr4](https://discourse.slicer.org/u/fieldr4)\
**Post date:** [November 29, 2022, 3:10pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/23 "2022-11-29T15:10:43Z")

</div>

VerSe 2020 \> 03\_test \> verse 563.nii

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/3/6/36f544253c5cf91b1aeb8eee0b0552e0d1d00d38.jpeg)

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

---

<div class="post-metadata">

**Author:** ![Mik](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@Mik](https://discourse.slicer.org/u/Mik)\
**Post date:** [November 30, 2022, 3:57am UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/24 "2022-11-30T03:57:57Z")

</div>

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.

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

```

---

<div class="post-metadata">

**Author:** ![fieldr4](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@fieldr4](https://discourse.slicer.org/u/fieldr4)\
**Post date:** [November 30, 2022, 4:34am UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/25 "2022-11-30T04:34:33Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Mik](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@Mik](https://discourse.slicer.org/u/Mik)\
**Post date:** [November 30, 2022, 4:44am UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/26 "2022-11-30T04:44:11Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Mik](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@Mik](https://discourse.slicer.org/u/Mik)\
**Post date:** [November 30, 2022, 2:23pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/27 "2022-11-30T14:23:27Z")

</div>

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

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

```

---

<div class="post-metadata">

**Author:** ![fieldr4](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@fieldr4](https://discourse.slicer.org/u/fieldr4)\
**Post date:** [November 30, 2022, 11:01pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/28 "2022-11-30T23:01:17Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [December 1, 2022, 1:35am UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/29 "2022-12-01T01:35:52Z")

</div>

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:

```auto
[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.

---

<div class="post-metadata">

**Author:** ![Mik](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@Mik](https://discourse.slicer.org/u/Mik)\
**Post date:** [December 1, 2022, 1:01pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/30 "2022-12-01T13:01:46Z")

</div>

> [@lassoan](#):
>
> 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.

---

<div class="post-metadata">

**Author:** ![gcsharp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/gcsharp/32/863_2.png) [@gcsharp](https://discourse.slicer.org/u/gcsharp)\
**Post date:** [December 1, 2022, 6:25pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/31 "2022-12-01T18:25:37Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Mik](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@Mik](https://discourse.slicer.org/u/Mik)\
**Post date:** [December 2, 2022, 6:21am UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/32 "2022-12-02T06:21:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![fieldr4](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@fieldr4](https://discourse.slicer.org/u/fieldr4)\
**Post date:** [December 5, 2022, 10:36pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/33 "2022-12-05T22:36:37Z")

</div>

Hi Mik, Andras, and Greg,

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

> [@Mik](#):
>
> ```auto
> mat = vtk.vtkMatrix4x4()
> mat.SetElement(0, 0, -1.)
> mat.SetElement(1, 1, -1.)
> ct = slicer.mrmlScene.GetFirstNodeByClass('vtkMRMLScalarVolumeNode')
> ct.SetIJKToRASMatrix(mat)
> 
> ```

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.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [December 6, 2022, 3:46pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/34 "2022-12-06T15:46:37Z")

</div>

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:

> <https://github.com/gaoyi/SlicerBigImage/blob/08a898fe7a40338ed4e6f4566f27153e012ff1e9/NgffImageIO/NgffImageIO.py#L108-L113>

---

<div class="post-metadata">

**Author:** ![fieldr4](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@fieldr4](https://discourse.slicer.org/u/fieldr4)\
**Post date:** [December 7, 2022, 4:05pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/35 "2022-12-07T16:05:43Z")

</div>

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.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/8/4/8477f1a8ab2dba6f6a0c75169c273fb8586491c9.jpeg)

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [December 8, 2022, 3:28am UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/36 "2022-12-08T03:28:52Z")

</div>

> [@fieldr4](#):
>
> What is the syntax for selecting a DataNode for this transformation?

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.

---

<div class="post-metadata">

**Author:** ![fieldr4](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@fieldr4](https://discourse.slicer.org/u/fieldr4)\
**Post date:** [December 8, 2022, 4:07am UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/37 "2022-12-08T04:07:45Z")

</div>

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:

```auto
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.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/b/4/b43b517c987f6fb818f8a38c988bcbf98e3f9578.jpeg)

Here is a screenshot of the resulting DRR.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/0/e/0ea7d2355fadffdb500fc4adbdae14cf486116ec.jpeg)

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!

---

<div class="post-metadata">

**Author:** ![fieldr4](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@fieldr4](https://discourse.slicer.org/u/fieldr4)\
**Post date:** [December 8, 2022, 6:54pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/38 "2022-12-08T18:54:04Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![fieldr4](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@fieldr4](https://discourse.slicer.org/u/fieldr4)\
**Post date:** [December 9, 2022, 2:47pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/39 "2022-12-09T14:47:35Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Mik](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@Mik](https://discourse.slicer.org/u/Mik)\
**Post date:** [December 9, 2022, 4:08pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/40 "2022-12-09T16:08:11Z")

</div>

> [@fieldr4](#):
>
> Hi Mik, have you made any progress on adding support of oriented volumes?

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.

---

<div class="post-metadata">

**Author:** ![fieldr4](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@fieldr4](https://discourse.slicer.org/u/fieldr4)\
**Post date:** [December 9, 2022, 4:43pm UTC](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010/41 "2022-12-09T16:43:07Z")

</div>

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.

[Previous page](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010.md?page=1)

[Next page](https://discourse.slicer.org/t/generate-digitally-reconstructed-radiograph-from-3dct/2010.md?page=3)
