pydicom
pydicom is a pure Python package for working with DICOM files, the standard for medical imaging and related information. It facilitates reading, modifying, and writing DICOM data into natural pythonic structures. The current version is 3.0.2, and it maintains an active development cycle with several releases per year, including major versions that introduce breaking changes.
Warnings
- breaking The functions `read_file()` and `write_file()` have been removed in pydicom v3.0. Users should now use `pydicom.dcmread()` and `pydicom.dcmwrite()` respectively. Additionally, `Dataset.pixel_array` now converts YCbCr Pixel Data to RGB by default. Python versions older than 3.10 are no longer supported.
- breaking The main package import changed from `import dicom` to `import pydicom` in v1.0. Older code relying on `import dicom` will fail.
- deprecated The `pydicom.pixel_data_handlers` module is deprecated and will be removed in v4.0. Users should migrate to the `pydicom.pixels` module for pixel data handling.
- gotcha Handling compressed pixel data (e.g., JPEG, JPEG 2000) requires additional, optional third-party libraries (`numpy`, `pillow`, `gdcm`, `jpeg_ls`, `pylibjpeg` with its plugins). `PixelData` stores raw bytes, and direct modification of compressed pixel data usually requires decompression first.
- gotcha Accessing private DICOM tags by keyword (e.g., `ds.PrivateTag`) is generally not possible. They must be accessed by their tag number (e.g., `ds[0xGGXXEEEE]`) or iterated using `ds.dir()` and inspected.
- gotcha To prepare for future breaking changes, pydicom provides a 'future behavior' flag. Running with this flag can help identify code incompatibilities with upcoming major versions.
Install
-
pip install pydicom -
conda install -c conda-forge pydicom
Imports
- pydicom
import pydicom
- dcmread
from pydicom import dcmread
- Dataset
from pydicom.dataset import Dataset
Quickstart
import os
import pydicom
from pydicom.data import get_testdata_files
# Create a dummy DICOM file for demonstration if it doesn't exist
# In a real scenario, you would read an existing .dcm file.
try:
# Using a test file provided by pydicom
filename = get_testdata_files("CT_small.dcm")[0]
ds = pydicom.dcmread(filename)
print(f"Successfully read: {filename}")
except Exception as e:
print(f"Could not read test file: {e}. Creating a minimal dataset.")
# Create a dummy dataset if test files are unavailable or for new creation
from pydicom.dataset import Dataset, FileDataset, FileMetaDataset
from pydicom.uid import generate_uid
file_meta = FileMetaDataset()
file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' # CT Image Storage
file_meta.MediaStorageSOPInstanceUID = generate_uid()
file_meta.ImplementationClassUID = generate_uid()
ds = FileDataset("dummy.dcm", {}, file_meta=file_meta, preamble=b"\0" * 128)
ds.PatientName = "Doe^John"
ds.PatientID = "123456"
ds.Modality = "CT"
ds.StudyInstanceUID = generate_uid()
ds.SeriesInstanceUID = generate_uid()
ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
ds.SOPClassUID = file_meta.MediaStorageSOPClassUID
ds.BodyPartExamined = "CHEST"
ds.Rows = 128
ds.Columns = 128
ds.BitsAllocated = 16
ds.BitsStored = 12
ds.HighBit = 11
ds.PixelRepresentation = 0 # unsigned
ds.PhotometricInterpretation = "MONOCHROME2"
ds.SamplesPerPixel = 1
ds.PixelData = b'\x00\x00' * ds.Rows * ds.Columns # Dummy pixel data
ds.is_little_endian = True
ds.is_implicit_VR = False
ds.save_as("dummy.dcm")
filename = "dummy.dcm"
ds = pydicom.dcmread(filename)
# Accessing DICOM elements
print(f"Patient Name: {ds.PatientName}")
print(f"Modality: {ds.Modality}")
# Modifying DICOM elements
ds.PatientName = "Smith^Jane"
print(f"New Patient Name: {ds.PatientName}")
# Adding new elements (if not present in the dictionary, define VR first)
if 'PhysicianOfRecord' not in ds:
ds.add_new('00080090', 'PN', 'Dr. Who') # Tag, VR, Value
else:
ds.PhysicianOfRecord = 'Dr. New'
print(f"Physician Of Record: {ds.PhysicianOfRecord}")
# Saving the modified dataset to a new file
output_filename = "modified_image.dcm"
ds.save_as(output_filename)
print(f"Modified DICOM saved to: {output_filename}")
# Accessing pixel data (requires numpy)
if 'PixelData' in ds and 'numpy' in globals():
try:
pixel_array = ds.pixel_array
print(f"Pixel data shape: {pixel_array.shape}")
except Exception as e:
print(f"Could not access pixel_array: {e}. Is numpy installed?")
# Clean up (optional)
# os.remove(output_filename)
# if filename == "dummy.dcm":
# os.remove(filename)