Skip to content

Instantly share code, notes, and snippets.

@mcdlee
Last active October 21, 2021 06:22
Show Gist options
  • Save mcdlee/8300430 to your computer and use it in GitHub Desktop.
Save mcdlee/8300430 to your computer and use it in GitHub Desktop.
PET/CT parsing to a Numpy 3D array
import dicom
import os
import numpy
import pylab
# readind data
ds = dicom.read_file("DICOMDIR") # read a dicomdir of PET/CT
# collect pixel_volume and resolution
def getSec(s):
b =int(s[0:2]) *3600 + int(s[2:4])*60 + int(s[4:6])
return b
for record in ds.DirectoryRecordSequence:
if record.DirectoryRecordType == "IMAGE":
if record.ImageID == "PET AC 2D":
path = os.path.join(*record.ReferencedFileID)
dcm = dicom.read_file(path)
pixel_spacing = dcm.PixelSpacing[1]
slice_thickness = record.SliceThickness
row = dcm.Rows
column = dcm.Columns
slice_number = dcm.InstanceNumber
body_weight = dcm.PatientWeight *1000
injection_time = getSec(dcm.RadiopharmaceuticalInformationSequence[0].RadiopharmaceuticalStartTime)
acqusition_time = getSec(dcm.AcquisitionTime)
dose = dcm.RadiopharmaceuticalInformationSequence[0].RadionuclideTotalDose
half_life = dcm.RadiopharmaceuticalInformationSequence[0].RadionuclideHalfLife
break
actural_dose = dose * 0.5**((acqusition_time-injection_time)/half_life)
pixel_volume = pixel_spacing ** 2 * slice_thickness/1000
print("pixel size =", pixel_spacing, "x", pixel_spacing, "x", slice_thickness, "mm")
print("pixel volume=", pixel_volume, "cc")
print("This image is", row, "x", column, "x", slice_number)
pixel_data = numpy.ones((slice_number,row,column))
#combine the arrays into 3D dataset
i = slice_number-1 #Because our scan is from pelvis to head
for record in ds.DirectoryRecordSequence: #https://groups.google.com/forum/#!msg/pydicom/TR2nl6_JRtM/aDODx-eNUTcJ
if record.DirectoryRecordType == "IMAGE":
if record.ImageID == "PET AC 2D":
# Extract the relative path to the DICOM file
path = os.path.join(*record.ReferencedFileID)
dcm = dicom.read_file(path)
SUV = dcm.pixel_array * body_weight / actural_dose * record[0x0028, 0x1053].value # Rescale Slope
# Now get your image data
pixel_data[i,:,:] = SUV
i = i-1
@jasonsiffre
Copy link

Your conversion into seconds is false
def getSec(s):
b =int(s[0:2]) *3600 + int(s[2:4])*60 + int(s[5:6]).
return b

It should be :
def getSec(s):
b =int(s[0:2]) *3600 + int(s[2:4])*60 + int(s[4:6]).
return b

Also be carefull as AcquisitionTime change over slices

@mcdlee
Copy link
Author

mcdlee commented Oct 18, 2021

Thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment