Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting DICOM structure contours as array in Python

Tags:

dicom

pydicom

So if I have an image (CT, MRI, etc.) or even a dose from radiation therapy I can pull out the dose or image values into an array through:

import dicom

ds = dicom.read_file("dicom_file.dcm")

print ds.pixel_array

This is pretty straightforward, and gives me the ability to manipulate images/doses as I want. However, often you also have a structure file that includes different contoured structures that you can then see in an image viewer or something like that. Again, pretty straightforward.

My problem is that I would also like these individual structures as an array as well. And if I run the same code I just get TypeError: No pixel data found in this dataset.

I'm guessing that structure DICOM files are not "made" the same way as dose/images DICOM files.

So is there a solution to this that I haven't been able to find ? I have also looked at the dicompyler_core package, but from what I could see there wasn't any way to "just" get out the different structures into arrays.

The SOP Class UID of the DICOM file in question is RT Structure Set Storage.

like image 325
Denver Dang Avatar asked Oct 10 '17 12:10

Denver Dang


1 Answers

Here is an interactive session illustrating the data layout using the rtstruct.dcm file included with pydicom:

>>> import dicom
>>> ds = dicom.read_file("rtstruct.dcm", force=True)
>>> ds.dir("contour")
['ROIContourSequence']
>>> ctrs = ds.ROIContourSequence
>>> ctrs[0]
(3006, 002a) ROI Display Color                   IS: ['220', '160', '120']
(3006, 0040)  Contour Sequence   3 item(s) ----
   (3006, 0042) Contour Geometric Type              CS: 'CLOSED_PLANAR'
   (3006, 0046) Number of Contour Points            IS: '5'
   (3006, 0048) Contour Number                      IS: '1'
   (3006, 0050) Contour Data                        DS: ['-200.0', '150.0', '-20
0.0', '-200.0', '-150.0', '-200.0', '200.0', '-150.0', '-200.0', '200.0', '150.0
', '-200.0', '-200.0', '150.0', '-200.0']
   ---------
   (3006, 0042) Contour Geometric Type              CS: 'CLOSED_PLANAR'
   (3006, 0046) Number of Contour Points            IS: '6'
   (3006, 0048) Contour Number                      IS: '2'
   (3006, 0050) Contour Data                        DS: ['200.0', '-0.0', '-190.
0', '200.0', '-150.0', '-190.0', '-200.0', '-150.0', '-190.0', '-200.0', '150.0'
, '-190.0', '200.0', '150.0', '-190.0', '200.0', '-0.0', '-190.0']
   ---------
   (3006, 0042) Contour Geometric Type              CS: 'CLOSED_PLANAR'
   (3006, 0046) Number of Contour Points            IS: '6'
   (3006, 0048) Contour Number                      IS: '3'
   (3006, 0050) Contour Data                        DS: ['200.0', '-0.0', '-180.
0', '200.0', '-150.0', '-180.0', '-200.0', '-150.0', '-180.0', '-200.0', '150.0'
, '-180.0', '200.0', '150.0', '-180.0', '200.0', '-0.0', '-180.0']
   ---------
(3006, 0084) Referenced ROI Number               IS: '1'

The data is stored (in this case, as is usual) as a set of coordinates for each plane. To get the data for one contour, for one plane, you could use

>>> ctrs[0].ContourSequence[0].ContourData
['-200.0', '150.0', '-200.0', '-200.0', '-150.0', '-200.0', '200.0', '-150.0', '
-200.0', '200.0', '150.0', '-200.0', '-200.0', '150.0', '-200.0']

These are triplets of (x, y, z) coordinates one after the other.

You can find out more information about each contour (name, etc) in the StructureSetROISequence sequence, for the index given by Referenced ROI Number.

You could get a complete array for all of these by looping through each dataset in the ContourSequence for that particular contour and appending them together into one array.

like image 91
darcymason Avatar answered Nov 14 '22 21:11

darcymason