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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With