Skip to content
pydicom logo

Pydicom

pydicom

Python library for working with DICOM (Digital Imaging and Communications in Medicine) files. Use this skill when reading, writing, or modifying medical imaging data in DICOM format, extracting pixel data from medical images (CT, MRI, X-ray, ultrasound), anonymizing DICOM files, working with DICO...

SKILL.md

Full skill instructions

Pydicom

Overview

Pydicom is a pure Python package for working with DICOM files, the standard format for medical imaging data. This skill provides guidance on reading, writing, and manipulating DICOM files, including working with pixel data, metadata, and various compression formats.

When to Use This Skill

Use this skill when working with:

  • Medical imaging files (CT, MRI, X-ray, ultrasound, PET, etc.)
  • DICOM datasets requiring metadata extraction or modification
  • Pixel data extraction and image processing from medical scans
  • DICOM anonymization for research or data sharing
  • Converting DICOM files to standard image formats
  • Compressed DICOM data requiring decompression
  • DICOM sequences and structured reports
  • Multi-slice volume reconstruction
  • PACS (Picture Archiving and Communication System) integration

Installation

Install pydicom and common dependencies:

uv pip install pydicom
uv pip install pillow  # For image format conversion
uv pip install numpy   # For pixel array manipulation
uv pip install matplotlib  # For visualization

For handling compressed DICOM files, additional packages may be needed:

uv pip install pylibjpeg pylibjpeg-libjpeg pylibjpeg-openjpeg  # JPEG compression
uv pip install python-gdcm  # Alternative compression handler

Core Workflows

Reading DICOM Files

Read a DICOM file using pydicom.dcmread():

import pydicom

# Read a DICOM file
ds = pydicom.dcmread('path/​to/​file.dcm')

# Access metadata
print(f"Patient Name: {ds.PatientName}")
print(f"Study Date: {ds.StudyDate}")
print(f"Modality: {ds.Modality}")

# Display all elements
print(ds)

Key points:

  • dcmread() returns a Dataset object
  • Access data elements using attribute notation (e.g., ds.PatientName) or tag notation (e.g., ds[0x0010, 0x0010])
  • Use ds.file_meta to access file metadata like Transfer Syntax UID
  • Handle missing attributes with getattr(ds, 'AttributeName', default_value) or hasattr(ds, 'AttributeName')

Working with Pixel Data

Extract and manipulate image data from DICOM files:

import pydicom
import numpy as np
import matplotlib.pyplot as plt

# Read DICOM file
ds = pydicom.dcmread('image.dcm')

# Get pixel array (requires numpy)
pixel_array = ds.pixel_array

# Image information
print(f"Shape: {pixel_array.shape}")
print(f"Data type: {pixel_array.dtype}")
print(f"Rows: {ds.Rows}, Columns: {ds.Columns}")

# Apply windowing for display (CT/​MRI)
if hasattr(ds, 'WindowCenter') and hasattr(ds, 'WindowWidth'):
    from pydicom.pixel_data_handlers.util import apply_voi_lut
    windowed_image = apply_voi_lut(pixel_array, ds)
else:
    windowed_image = pixel_array

# Display image
plt.imshow(windowed_image, cmap='gray')
plt.title(f"{ds.Modality} - {ds.StudyDescription}")
plt.axis('off')
plt.show()

Working with color images:

# RGB images have shape (rows, columns, 3)
if ds.PhotometricInterpretation == 'RGB':
    rgb_image = ds.pixel_array
    plt.imshow(rgb_image)
elif ds.PhotometricInterpretation == 'YBR_FULL':
    from pydicom.pixel_data_handlers.util import convert_color_space
    rgb_image = convert_color_space(ds.pixel_array, 'YBR_FULL', 'RGB')
    plt.imshow(rgb_image)

Multi-frame images (videos/​series):

# For multi-frame DICOM files
if hasattr(ds, 'NumberOfFrames') and ds.NumberOfFrames > 1:
    frames = ds.pixel_array  # Shape: (num_frames, rows, columns)
    print(f"Number of frames: {frames.shape[0]}")

    # Display specific frame
    plt.imshow(frames[0], cmap='gray')

Converting DICOM to Image Formats

Use the provided dicom_to_image.py script or convert manually:

from PIL import Image
import pydicom
import numpy as np

ds = pydicom.dcmread('input.dcm')
pixel_array = ds.pixel_array

# Normalize to 0-255 range
if pixel_array.dtype != np.uint8:
    pixel_array = ((pixel_array - pixel_array.min()) /
                   (pixel_array.max() - pixel_array.min()) * 255).astype(np.uint8)

# Save as PNG
image = Image.fromarray(pixel_array)
image.save('output.png')

Use the script: python scripts/​dicom_to_image.py input.dcm output.png

Modifying Metadata

Modify DICOM data elements:

import pydicom
from datetime import datetime

ds = pydicom.dcmread('input.dcm')

# Modify existing elements
ds.PatientName = "Doe^John"
ds.StudyDate = datetime.now().strftime('%Y%m%d')
ds.StudyDescription = "Modified Study"

# Add new elements
ds.SeriesNumber = 1
ds.SeriesDescription = "New Series"

# Remove elements
if hasattr(ds, 'PatientComments'):
    delattr(ds, 'PatientComments')
# Or using del
if 'PatientComments' in ds:
    del ds.PatientComments

# Save modified file
ds.save_as('modified.dcm')

Anonymizing DICOM Files

Remove or replace patient identifiable information:

import pydicom
from datetime import datetime

ds = pydicom.dcmread('input.dcm')

# Tags commonly containing PHI (Protected Health Information)
tags_to_anonymize = [
    'PatientName', 'PatientID', 'PatientBirthDate',
    'PatientSex', 'PatientAge', 'PatientAddress',
    'InstitutionName', 'InstitutionAddress',
    'ReferringPhysicianName', 'PerformingPhysicianName',
    'OperatorsName', 'StudyDescription', 'SeriesDescription',
]

# Remove or replace sensitive data
for tag in tags_to_anonymize:
    if hasattr(ds, tag):
        if tag in ['PatientName', 'PatientID']:
            setattr(ds, tag, 'ANONYMOUS')
        elif tag == 'PatientBirthDate':
            setattr(ds, tag, '19000101')
        else:
            delattr(ds, tag)

# Update dates to maintain temporal relationships
if hasattr(ds, 'StudyDate'):
    # Shift dates by a random offset
    ds.StudyDate = '20000101'

# Keep pixel data intact
ds.save_as('anonymized.dcm')

Use the provided script: python scripts/​anonymize_dicom.py input.dcm output.dcm

Writing DICOM Files

Create DICOM files from scratch:

import pydicom
from pydicom.dataset import Dataset, FileDataset
from datetime import datetime
import numpy as np

# Create file meta information
file_meta = Dataset()
file_meta.MediaStorageSOPClassUID = pydicom.uid.generate_uid()
file_meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid()
file_meta.TransferSyntaxUID = pydicom.uid.ExplicitVRLittleEndian

# Create the FileDataset instance
ds = FileDataset('new_dicom.dcm', {}, file_meta=file_meta, preamble=b"\0" * 128)

# Add required DICOM elements
ds.PatientName = "Test^Patient"
ds.PatientID = "123456"
ds.Modality = "CT"
ds.StudyDate = datetime.now().strftime('%Y%m%d')
ds.StudyTime = datetime.now().strftime('%H%M%S')
ds.ContentDate = ds.StudyDate
ds.ContentTime = ds.StudyTime

# Add image-specific elements
ds.SamplesPerPixel = 1
ds.PhotometricInterpretation = "MONOCHROME2"
ds.Rows = 512
ds.Columns = 512
ds.BitsAllocated = 16
ds.BitsStored = 16
ds.HighBit = 15
ds.PixelRepresentation = 0

# Create pixel data
pixel_array = np.random.randint(0, 4096, (512, 512), dtype=np.uint16)
ds.PixelData = pixel_array.tobytes()

# Add required UIDs
ds.SOPClassUID = pydicom.uid.CTImageStorage
ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
ds.SeriesInstanceUID = pydicom.uid.generate_uid()
ds.StudyInstanceUID = pydicom.uid.generate_uid()

# Save the file
ds.save_as('new_dicom.dcm')

Compression and Decompression

Handle compressed DICOM files:

import pydicom

# Read compressed DICOM file
ds = pydicom.dcmread('compressed.dcm')

# Check transfer syntax
print(f"Transfer Syntax: {ds.file_meta.TransferSyntaxUID}")
print(f"Transfer Syntax Name: {ds.file_meta.TransferSyntaxUID.name}")

# Decompress and save as uncompressed
ds.decompress()
ds.save_as('uncompressed.dcm', write_like_original=False)

# Or compress when saving (requires appropriate encoder)
ds_uncompressed = pydicom.dcmread('uncompressed.dcm')
ds_uncompressed.compress(pydicom.uid.JPEGBaseline8Bit)
ds_uncompressed.save_as('compressed_jpeg.dcm')

Common transfer syntaxes:

  • ExplicitVRLittleEndian - Uncompressed, most common
  • JPEGBaseline8Bit - JPEG lossy compression
  • JPEGLossless - JPEG lossless compression
  • JPEG2000Lossless - JPEG 2000 lossless
  • RLELossless - Run-Length Encoding lossless

See references/​transfer_syntaxes.md for complete list.

Working with DICOM Sequences

Handle nested data structures:

import pydicom

ds = pydicom.dcmread('file.dcm')

# Access sequences
if 'ReferencedStudySequence' in ds:
    for item in ds.ReferencedStudySequence:
        print(f"Referenced SOP Instance UID: {item.ReferencedSOPInstanceUID}")

# Create a sequence
from pydicom.sequence import Sequence

sequence_item = Dataset()
sequence_item.ReferencedSOPClassUID = pydicom.uid.CTImageStorage
sequence_item.ReferencedSOPInstanceUID = pydicom.uid.generate_uid()

ds.ReferencedImageSequence = Sequence([sequence_item])

Processing DICOM Series

Work with multiple related DICOM files:

import pydicom
import numpy as np
from pathlib import Path

# Read all DICOM files in a directory
dicom_dir = Path('dicom_series/')
slices = []

for file_path in dicom_dir.glob('*.dcm'):
    ds = pydicom.dcmread(file_path)
    slices.append(ds)

# Sort by slice location or instance number
slices.sort(key=lambda x: float(x.ImagePositionPatient[2]))
# Or: slices.sort(key=lambda x: int(x.InstanceNumber))

# Create 3D volume
volume = np.stack([s.pixel_array for s in slices])
print(f"Volume shape: {volume.shape}")  # (num_slices, rows, columns)

# Get spacing information for proper scaling
pixel_spacing = slices[0].PixelSpacing  # [row_spacing, col_spacing]
slice_thickness = slices[0].SliceThickness
print(f"Voxel size: {pixel_spacing[0]}x{pixel_spacing[1]}x{slice_thickness} mm")

Helper Scripts

This skill includes utility scripts in the scripts/ directory:

anonymize_dicom.py

Anonymize DICOM files by removing or replacing Protected Health Information (PHI).

python scripts/​anonymize_dicom.py input.dcm output.dcm

dicom_to_image.py

Convert DICOM files to common image formats (PNG, JPEG, TIFF).

python scripts/​dicom_to_image.py input.dcm output.png
python scripts/​dicom_to_image.py input.dcm output.jpg --format JPEG

extract_metadata.py

Extract and display DICOM metadata in a readable format.

python scripts/​extract_metadata.py file.dcm
python scripts/​extract_metadata.py file.dcm --output metadata.txt

Reference Materials

Detailed reference information is available in the references/ directory:

  • common_tags.md: Comprehensive list of commonly used DICOM tags organized by category (Patient, Study, Series, Image, etc.)
  • transfer_syntaxes.md: Complete reference of DICOM transfer syntaxes and compression formats

Common Issues and Solutions

Issue: "Unable to decode pixel data"

  • Solution: Install additional compression handlers: uv pip install pylibjpeg pylibjpeg-libjpeg python-gdcm

Issue: "AttributeError" when accessing tags

  • Solution: Check if attribute exists with hasattr(ds, 'AttributeName') or use ds.get('AttributeName', default)

Issue: Incorrect image display (too dark/​bright)

  • Solution: Apply VOI LUT windowing: apply_voi_lut(pixel_array, ds) or manually adjust with WindowCenter and WindowWidth

Issue: Memory issues with large series

  • Solution: Process files iteratively, use memory-mapped arrays, or downsample images

Best Practices

  1. Always check for required attributes before accessing them using hasattr() or get()
  2. Preserve file metadata when modifying files by using save_as() with write_like_original=True
  3. Use Transfer Syntax UIDs to understand compression format before processing pixel data
  4. Handle exceptions when reading files from untrusted sources
  5. Apply proper windowing (VOI LUT) for medical image visualization
  6. Maintain spatial information (pixel spacing, slice thickness) when processing 3D volumes
  7. Verify anonymization thoroughly before sharing medical data
  8. Use UIDs correctly - generate new UIDs when creating new instances, preserve them when modifying

Documentation

Official pydicom documentation: https://pydicom.github.io/pydicom/dev/

More skills from Dicklesworthstone

environment-setup-guide logo
Dicklesworthstone/pi_agent_rust

environment-setup-guide

Guide developers through setting up development environments with proper tools, dependencies, and configurations

1.8K 0
View
exa-policy-guardrails logo
Dicklesworthstone/pi_agent_rust

exa-policy-guardrails

Implement Exa lint rules, policy enforcement, and automated guardrails. Use when setting up code quality rules for Exa integrations, implementing pre-commit hooks, or configuring CI policy checks for Exa best practices. Trigger with phrases like "exa policy", "exa lint", "exa guardrails", "exa be...

1.8K 0
View
documenso-ci-integration logo
Dicklesworthstone/pi_agent_rust

documenso-ci-integration

Configure CI/CD pipelines for Documenso integrations. Use when setting up automated testing, deployment pipelines, or continuous integration for Documenso projects. Trigger with phrases like "documenso CI", "documenso GitHub Actions", "documenso pipeline", "documenso automated testing".

1.8K 0
View
openrouter-model-availability logo
Dicklesworthstone/pi_agent_rust

openrouter-model-availability

Build check model availability and implement fallback chains. Use when building resilient systems or handling model outages. Trigger with phrases like 'openrouter availability', 'openrouter fallback', 'openrouter model down', 'openrouter health check'.

1.8K 0
View
langfuse-enterprise-rbac logo
Dicklesworthstone/pi_agent_rust

langfuse-enterprise-rbac

Configure Langfuse enterprise organization management and access control. Use when implementing team access controls, configuring organization settings, or setting up role-based permissions for Langfuse projects. Trigger with phrases like "langfuse RBAC", "langfuse teams", "langfuse organization"...

1.8K 0
View
cursor-compliance-audit logo
Dicklesworthstone/pi_agent_rust

cursor-compliance-audit

Execute compliance and security auditing for Cursor usage. Triggers on "cursor compliance", "cursor audit", "cursor security review", "cursor soc2", "cursor gdpr". Use when analyzing or auditing cursor compliance audit. Trigger with phrases like "cursor compliance audit", "cursor audit", "cursor".

1.8K 0
View
apollo-ci-integration logo
Dicklesworthstone/pi_agent_rust

apollo-ci-integration

Configure Apollo.io CI/CD integration. Use when setting up automated testing, continuous integration, or deployment pipelines for Apollo integrations. Trigger with phrases like "apollo ci", "apollo github actions", "apollo pipeline", "apollo ci/cd", "apollo automated tests".

1.8K 0
View
python-script logo
Dicklesworthstone/pi_agent_rust

python-script

Create robust Python automation with full logging and safety checks. Use when tasks need complex data processing, authenticated API work, conditional file operations, or error handling beyond simple shell commands.

1.8K 0
View
posthog-multi-env-setup logo
Dicklesworthstone/pi_agent_rust

posthog-multi-env-setup

Configure PostHog across development, staging, and production environments. Use when setting up multi-environment deployments, configuring per-environment secrets, or implementing environment-specific PostHog configurations. Trigger with phrases like "posthog environments", "posthog staging", "po...

1.8K 0
View
ai-agents-architect logo
Dicklesworthstone/pi_agent_rust

ai-agents-architect

Expert in designing and building autonomous AI agents. Masters tool use, memory systems, planning strategies, and multi-agent orchestration. Use when: build agent, AI agent, autonomous agent, tool use, function calling.

1.8K 0
View
insecure-deserialization-checker logo
Dicklesworthstone/pi_agent_rust

insecure-deserialization-checker

Validate insecure deserialization checker operations. Auto-activating skill for Security Fundamentals. Triggers on: insecure deserialization checker, insecure deserialization checker Part of the Security Fundamentals skill category. Use when working with insecure deserialization checker functiona...

1.8K 0
View
path-traversal-finder logo
Dicklesworthstone/pi_agent_rust

path-traversal-finder

Manage path traversal finder operations. Auto-activating skill for Security Fundamentals. Triggers on: path traversal finder, path traversal finder Part of the Security Fundamentals skill category. Use when working with path traversal finder functionality. Trigger with phrases like "path traversa...

1.8K 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View