Matching CT and RT dose coordinates

3,045 views
Skip to first unread message

Jothy

unread,
Feb 23, 2011, 12:38:14 PM2/23/11
to gdcm-developers, VTK Mailing List, itk, python-...@googlegroups.com
Hi all,

I am trying to overlay an dose shade on a CT slice.I am using vtkDICOMImageReader to read the CT and vtkGDCMImageReader to display the dose shade.But I am having problem with the coordinates.How to relate the coordinates? For e.g: I  get ImagePositionPatient of CT image for central slice as [-275,-524,-128.25] and ImagePositionPatient for dose as [-228.65,-419.25,-122.5] adn their spacings are [1.074,1.074,3] and [2.52.5.2.5] respectively for CT and Rt dose.

The image looks as in the attached figure.

Any hint

Thanks

Jothy
CTwithDose.JPG

Kantor,Michael E

unread,
Feb 23, 2011, 12:43:52 PM2/23/11
to python-...@googlegroups.com

Are you resampling dose to match the CT spacing?

Jothy

unread,
Feb 23, 2011, 12:48:25 PM2/23/11
to python-...@googlegroups.com
No, but I tried with a finer sampling than the CT earlier!

Does resampling has anythibg to do?

Thanks

Jothy

Kantor,Michael E

unread,
Feb 23, 2011, 12:54:37 PM2/23/11
to python-...@googlegroups.com

I just wasn’t sure how you were going about getting these into the pixle-space, but I guess vtkGDCMImageReader does that internally.

Scott Johnson

unread,
Feb 23, 2011, 1:04:03 PM2/23/11
to Jothy, gdcm-developers, VTK Mailing List, itk, python-...@googlegroups.com

If the FrameOfReferenceUIDs of the CT and the RT dose are the same, they both exist in the same coordinate system, if they don’t, you will have to register the dose to the CT somehow.

 

Because the resolution of the dose will generally be different than the CT a reasonable strategy is to loop through your CT voxels and use the position at the center of that voxel to sample into the RT Dose grid.  When you sample into the RT Dose you may need to interpolate the actual dose value.  That dose value determines your shading.

 

The other issue to be aware of is that the dose grid may not completely cover the CT image data.  This is probably why the origins are different for your data.

 

                                -- Scott

 

From: vtkusers...@vtk.org [mailto:vtkusers...@vtk.org] On Behalf Of Jothy


Sent: Wednesday, February 23, 2011 11:38 AM
To: gdcm-developers; VTK Mailing List; itk; python-...@googlegroups.com

Mike Tallhamer

unread,
Feb 23, 2011, 1:10:37 PM2/23/11
to python-...@googlegroups.com
If they were exported using DICOM RT they should already share the same
coordinates. For the each dataset you need to construct the coordinates
from the PixelSpacing and ImagePositionPatient as follows. Below I'm
using pydicom to read in the dataset.

import dicom as dcm
import numpy
import glob

For the DICOM RT dose dataset:

ds = dcm.read_file('rtdose.dcm')

rows = ds.Rows
columns = ds.Columns
pixel_spacing = ds.PixelSpacing
image_position = ds.ImagePositionPatient

x = numpy.arange(columns)*pixel_spacing[0] + image_position[0]
y = numpy.arange(rows)*pixel_spacing[1] + image_position[1]
z = numpy.array(ds.GridFrameOffsetVector) + image_position[2]

The coordinate of the first pixel in the numpy array for the dose is
then (x[0], y[0], z[0])

For the CT dataset:

I read in all the CT images for a directory:

images = {}

for file in glob.glob(dataset_dir+'*'):
ds = dcm.read_file(file)

# Check to see if it is an image file.
if ds.SOPClassUID == '1.2.840.10008.5.1.4.1.1.2':
#
# Add the image to the images dictionary based on its z
coordinate position.
#
images[ds.ImagePositionPatient[2]] = ds.pixel_array
else:
pass

# The ImagePositionPatient tag gives you the x,y,z coordinates of the
center of
# the first pixel. The slices are randomly accessed so we don't know
which one
# we have after looping through the CT slice so we will set the z
position after
# sorting the z coordinates below.
image_position = ds.ImagePositionPatient

# Construct the z coordinate array from the image index.
z = slices.keys()
z.sort()
ct_z = numpy.array(z)

image_position[2] = ct_z[0]

# The pixel spacing or planar resolution in the x and y directions.
ct_pixel_spacing = ds.PixelSpacing

# Verify z dimension spacing
b = ct_z[1:] - ct_z[0:-1]

z_spacing = 2.5 # Typical spacing for our institution

if b.min() == b.max():
z_spacing = b.max()

# Append z spacing so you have x,y,z spacing for the array.
ct_pixel_spacing.append(z_spacing)

# Build the z ordered 3D CT dataset array.
ct_array = np.array([slices[i] for i in z])

# Now construct the coordinate arrays
x = numpy.arange(ct_array.shape[2])*ct_pixel_spacing[0] + image_position[0]
y = numpy.arange(ct_array.shape[1])*ct_pixel_spacing[1] + image_position[1]
z = (numpy.arange(ct_array.shape[0])*z_spacing) + image_position[2]

The coordinate of the first pixel in the numpy array for the ct is then
(x[0], y[0], z[0])

These two datasets are now registered in the same coordinate space. If
you want to visualize them using VTK you need to transpose the numpy
arrays since VTK expects the increase in coordinates to be x, followed
by y followed by z while numpy has the opposite.

Thanks to Steve for helping me with this for the dose grid a few months
back. The CT stuff above is just an extension of what he shared with me.

The above code works for me using Mayavi which in turn uses VTK for the
visualization.

-Mike

Xiaofeng Z

unread,
Feb 23, 2011, 3:38:48 PM2/23/11
to joth...@gmail.com, gdcm-de...@lists.sourceforge.net, VTK, ITK Users, python-...@googlegroups.com
The position of RT Dose grid is usually stored as relative to the referenced image in Grid Frame Offset Vector.  Do you know if GDCM corrected for that?

Xiaofeng Zhao





Date: Wed, 23 Feb 2011 17:38:14 +0000
From: joth...@gmail.com
To: gdcm-de...@lists.sourceforge.net; vtku...@vtk.org; Insigh...@itk.org; python-...@googlegroups.com

Subject: [vtkusers] Matching CT and RT dose coordinates

_______________________________________________ Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ Follow this link to subscribe/unsubscribe: http://www.vtk.org/mailman/listinfo/vtkusers

Mark Roden

unread,
Feb 23, 2011, 4:06:44 PM2/23/11
to Jothy, gdcm-developers, VTK Mailing List, itk, python-...@googlegroups.com
Hi Jothy,

What are the direction cosines?

There is a problem where VTK reinterprets the direction cosines to
change the directions of images produced by the dicom reader.

DICOM specifies that the image patient position is always the upper
left pixel (if you look at the image as a 2D image on a plane like a
monitor). VTK will take the direction cosine and potentially flip the
image along those cosines.

Mark

> ------------------------------------------------------------------------------
> Free Software Download: Index, Search & Analyze Logs and other IT data in
> Real-Time with Splunk. Collect, index and harness all the fast moving IT
> data
> generated by your applications, servers and devices whether physical,
> virtual
> or in the cloud. Deliver compliance at lower cost and gain new business
> insights. http://p.sf.net/sfu/splunk-dev2dev
> _______________________________________________
> Gdcm-developers mailing list
> Gdcm-de...@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gdcm-developers
>
>

Karthik Krishnan

unread,
Feb 24, 2011, 12:39:52 AM2/24/11
to Jothy, itk, VTK Mailing List, gdcm-developers, python-...@googlegroups.com
As others already mentioned, you need to re-inteprolate the dose volume onto the CT data. To do that you must use the grid frame offset vectors.

For all dose images I've encountered, the spacing between these grid planes (as specified by the grid frame offset vectors) is a constant, but this need not always be the case. If you want to be thorough you need to account for this. Several folks don't (for instance below is an excerpt from Varian's conformance statement):

"Dose Plane Spacing:
If Grid Frame Offset Vector (3004,000C) is present, it must contain offset values yielding equally spaced dose planes. Therefore, those values follow option a. in C.8.8.3.1 in Part 3 of [1]. RT Dose Instances having unequally spaced dose planes are not supported.
"

So for this specific case, where the grid plane spacing is the same, you could use the using the starting grid frame offset vector and the grid plane spacing and use the itk::ResampleImageFilter. Simply use GDCM to convert the images to MHD. Then set the spacing and origin to match the starting grid plane offset vector and the grid plane spacing..

If you load the images in to 3DSlicer, I believe they should already be re-interpolated and placed in the right coordinate system.


--
karthik




_____________________________________

Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.html

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ


Follow this link to subscribe/unsubscribe:

Adit Panchal

unread,
Feb 24, 2011, 1:16:13 AM2/24/11
to python-...@googlegroups.com, Karthik Krishnan, Jothy, itk, VTK Mailing List, gdcm-developers
The dataset looks like the test data from dicompyler. If that is the
case, then I know for a fact that the CT images and the dose planes
are coincident, since they I exported them from Varian Eclipse.

The only issue I can think of is that the incorrect rendering has
something to do with the pixel spacing of [1.074, 1.074] vs [2.5, 2.5]
for the dose grid and the CT data respectively along with an incorrect
origin. The top right corner of the dose plane is almost at the center
of the CT image, which needs to be transposed. The same test data
renders correctly in dicompyler.

Adit

> --
> Python in Medical Physics resources can be found at:
> https://sites.google.com/site/pythonmedphys/
>

Jothy

unread,
Feb 24, 2011, 9:51:44 AM2/24/11
to Adit Panchal, python-...@googlegroups.com, Karthik Krishnan, VTK Mailing List, gdcm-developers
You are absolutely corrcet - the data set is from dicompyler.

Thanks for providing the data set as part of the dicompyler.

Jothy

Jothy

unread,
Feb 24, 2011, 10:02:17 AM2/24/11
to python-...@googlegroups.com, Mike Tallhamer
Thanks very much!

Let me try on these.


Jothy

Sudharsan Madhavan

unread,
Mar 11, 2021, 3:20:45 PM3/11/21
to Python in Medical Physics
Thanks for providing this code. I used this code and this pacage https://github.com/brianmanderson/Dicom_RT_and_Images_to_Mask to register CT images, Dose, and Structure annotations to the patient coordinates.

Thanks,
Sudharsan

Prerak Mody

unread,
Oct 1, 2023, 4:49:45 PM10/1/23
to Python in Medical Physics
For future readers, I posted a solution here using python
Refs

Suman Gautam

unread,
Feb 7, 2024, 5:04:17 PM2/7/24
to Python in Medical Physics
Hi I am having issues in matching CT and RT dose coordiantes. I have attached below the code , Please help me.


d2.PNG


d1.PNG

ct.PNG

T Mutanga

unread,
Feb 8, 2024, 2:23:01 AM2/8/24
to python-...@googlegroups.com
Did you look at Slicer and slicetr? http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/SlicerRT
This problem is arlready solved.



--
You received this message because you are subscribed to the Google Groups "Python in Medical Physics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-medphys+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python-medphys/eb2cff38-f466-43fb-bd1c-43b1c468029dn%40googlegroups.com.

Suman Gautam

unread,
Feb 8, 2024, 10:14:18 AM2/8/24
to Python in Medical Physics

I am having issues in matching the CT and RT dose coordinates. Could you please help me?

I have attached below waht i get. and the codes.






ct.PNG


On Sunday, October 1, 2023 at 4:49:45 PM UTC-4 Prerak Mody wrote:
Reply all
Reply to author
Forward
0 new messages