pydicom – Writing & Content skill for AI agents
Reads, inspects, writes, transforms, and preflights local DICOM datasets and pixel data. Applies to DICOM metadata, transfer syntaxes, compression plugins, frames, private elements, JSON, and bounded de-identification review.
Install the pydicom skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/pydicom-cb8a9.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /pydicom – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/pydicom-cb8a9.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $pydicom – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/pydicom-cb8a9.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /pydicom – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/pydicom-cb8a9.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /pydicom – then describe the task you want done.
SKILL.md content
pydicom
Use pydicom for DICOM dataset I/O and pixel processing. Version 3.0.2 is the
current stable release reviewed here. It fixes CVE-2026-32711, a crafted
DICOMDIR path-traversal issue. pydicom 3.0.2 declares Python >=3.10; its
bundled DICOM dictionary is 2024c; the current DICOM Standard reviewed here is
2026d. No PACS, DIMSE, DICOMweb endpoint, or authenticated service is exercised
by this local-file skill.
Mandatory safety boundary
- Work only with local data that the user is authorized to access.
- DICOM metadata, file names, private elements, overlays, structured content,
and pixels may contain protected health information (PHI).
- Never print
Dataset, export full metadata/JSON, or log element values by
default. Use a documented allowlist and aggregate output.
- pydicom is a general DICOM framework, not a diagnostic viewer. Pixel output,
validation, conversion, and plugin availability are not diagnostic claims.
- De-identification is profile-, purpose-, recipient-, jurisdiction-, and
threat-context-specific. It requires privacy/DICOM expert verification.
- Never claim that a tag-removal script is DICOM PS3.15, HIPAA, GDPR, or other
compliance. Preserve originals and audit derived outputs.
- Treat deterministic pseudonymization keys and UID maps as re-identification
secrets: use least privilege and encrypted/managed secret storage, never
commit, sync, log, or share them with derivatives, and define backup,
rotation, revocation, and destruction procedures. A leaked key invalidates
the intended separation; rotation also changes deterministic mappings.
- Set explicit input-file, file-count, frame-count, decoded-byte, and output
limits before parsing untrusted or unusually large datasets.
Installation
Create or activate an isolated environment, then install the reviewed release
(the pixel-stack pins below require Python 3.12+ because of NumPy):
uv pip install "pydicom==3.0.2"Uncompressed pixel arrays and image rendering:
uv pip install "pydicom==3.0.2" "numpy==2.5.3" "Pillow==12.3.0"Install only the transfer-syntax plugins required by the deployment:
# JPEG/JPEG-LS, JPEG 2000/HTJ2K, and faster RLE through pylibjpeg
uv pip install "numpy==2.5.3" "pylibjpeg==2.1.0" \
"pylibjpeg-libjpeg==2.4.0" "pylibjpeg-openjpeg==2.6.0" \
"pylibjpeg-rle==2.2.0"
# JPEG-LS encoder/decoder
uv pip install "numpy==2.5.3" "pyjpegls==1.5.1"
# Alternative decoder with platform-specific wheels
uv pip install "python-gdcm==3.2.6"Plugin licenses and wheels differ by package/platform; review them before
deployment. Pillow has documented decoding limitations and pydicom cautions
that plugin output must be independently checked.
Native codec wheels widen the supply-chain and memory-safety boundary. For a
controlled deployment, resolve these exact pins on a trusted build host, lock
and verify wheel hashes/provenance, mirror approved artifacts internally, scan
them, and install with hash enforcement rather than resolving from the public
index at runtime.
Choose the workflow
1. Need an aggregate overview: run scripts/extract_metadata.py.
2. Need bounded technical checks: run scripts/dicom_inventory.py.
3. Need codec deployment preflight: run
scripts/transfer_syntax_inspector.py.
4. Need frame/memory planning: run scripts/pixel_frame_planner.py.
5. Need one non-diagnostic rendered frame: run
scripts/dicom_to_image.py.
6. Need a pseudonymized derivative: read the de-identification section, create
a site-reviewed action profile, then run scripts/anonymize_dicom.py and
scripts/deidentification_audit.py.
7. Need to check a sensitive UID map: run
scripts/uid_mapping_validator.py.
Read datasets safely
dcmread() returns a FileDataset, a Dataset subclass with File Format
state such as file_meta, preamble, and original encoding.
from pathlib import Path
import pydicom
path = Path("authorized/input.dcm")
ds = pydicom.dcmread(
path,
stop_before_pixels=True,
specific_tags=[
"SOPClassUID",
"Modality",
"Rows",
"Columns",
"NumberOfFrames",
],
)
technical = {
"sop_class": ds.get("SOPClassUID"),
"modality": ds.get("Modality"),
"rows": ds.get("Rows"),
"columns": ds.get("Columns"),
}Use:
stop_before_pixels=Truefor metadata-only work.specific_tags=[...]for a minimum allowlist.defer_size="1 MiB"when a later write must preserve large values.force=False(default).force=Trueonly bypasses the File Format header
check; it does not prove the bytes are valid DICOM.
Do not call print(ds), repr(ds), or iterate values into logs on clinical
data.
Dataset, DataElement, and sequences
Access standard elements by keyword and check for absence:
modality = ds.get("Modality", "UNSPECIFIED")
if "ReferencedImageSequence" in ds:
for item in ds.ReferencedImageSequence:
referenced_class = item.get("ReferencedSOPClassUID")Tag access, such as ds[0x0010, 0x0010], returns a DataElement; its .value
is separate. Sequence behaves like a list of nested Dataset items. Privacy
actions must recurse through every sequence item, not only the top level.
When creating a file, use FileMetaDataset for group 0002, keep dataset and
file-meta SOP UIDs consistent, set a Transfer Syntax UID, and write in enforced
File Format:
from pydicom import dcmwrite
from pydicom.dataset import FileDataset, FileMetaDataset
from pydicom.uid import CTImageStorage, ExplicitVRLittleEndian, generate_uid
meta = FileMetaDataset()
meta.MediaStorageSOPClassUID = CTImageStorage
meta.MediaStorageSOPInstanceUID = generate_uid()
meta.TransferSyntaxUID = ExplicitVRLittleEndian
ds = FileDataset(None, {}, file_meta=meta, preamble=b"\0" * 128)
ds.SOPClassUID = meta.MediaStorageSOPClassUID
ds.SOPInstanceUID = meta.MediaStorageSOPInstanceUID
# Add all attributes required by the selected IOD before writing.
dcmwrite("new.dcm", ds, enforce_file_format=True, overwrite=False)write_like_original is deprecated in pydicom 3.0; use
enforce_file_format. A successful write is not full PS3.3 IOD conformance.
UIDs and transfer syntax
The File Meta Information Transfer Syntax UID controls dataset encoding and
pixel compression:
ts = ds.file_meta.TransferSyntaxUID
summary = {
"uid": str(ts),
"name": ts.name,
"compressed": ts.is_compressed,
"implicit_vr": ts.is_implicit_VR,
"little_endian": ts.is_little_endian,
}pydicom 3.0 chooses write encoding from the Transfer Syntax UID before legacy
dataset flags. Do not replace structural UIDs (Transfer Syntax, SOP Class, or
coding-scheme UIDs) during pseudonymization. Instance/reference UID replacement
must be one-to-one and consistent across the complete declared scope.
Read [references/transfer_syntaxes.md](references/transfer_syntaxes.md) before
compression, decompression, or encapsulation.
Pixel data and frames
The stable pydicom.pixels API supports path-based, frame-specific decoding:
from pydicom.pixels import pixel_array
# Reads only the selected frame where the source permits it.
frame = pixel_array("authorized/image.dcm", index=0, raw=False)Shape semantics:
- grayscale single frame:
(rows, columns) - grayscale multi-frame:
(frames, rows, columns) - color single frame:
(rows, columns, samples) - color multi-frame:
(frames, rows, columns, samples)
raw=False converts YBR_FULL/YBR_FULL_422 to RGB; codec-specific
JPEG 2000 processing may also produce RGB. It is not a universal YBR converter; raw=True retains
the decoded color space after mandatory minimal processing. Use
iter_pixels(path, indices=[...]) for bounded multi-frame iteration.
For grayscale display, apply transforms in this order:
from pydicom.pixels import apply_modality_lut, apply_voi_lut
modality_values = apply_modality_lut(frame, ds)
display_values = apply_voi_lut(modality_values, ds, index=0)Modality LUT/rescale and VOI/windowing change display/value semantics.
Apply a declared Presentation LUT after VOI; avoid double inversion. Without
one, MONOCHROME1 requires reversed display polarity. Palette Color requires
apply_color_lut(). Presentation states and ICC behavior may require a
validated viewer. Never use per-frame min/max normalization for quantitative
analysis.
For enhanced multi-frame objects, inspect Shared/Per-Frame Functional Groups
for the selected frame before applying rescale or VOI transforms. The
[Pixel Value Transformation and Frame VOI macros](https://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.16.2.html)
may carry frame-specific parameters; top-level tags alone can be insufficient.
Confirm the output units and relevant real-world-value mapping before describing
decoded values as quantitative measurements. Do not assume a decoded array is
already in Hounsfield units or that every frame
… (full content is in the download package)
Related skills
- cloudflare-zero-trust – Protect internal apps with Cloudflare Access, device posture, and Zero Trust policies.
- cloudformation-best-practices – CloudFormation template optimization, nested stacks, drift detection, and…
- pymc – Builds and checks Bayesian models with PyMC, including hierarchical models, NUTS MCMC…
- jira-expert – Atlassian Jira expert for creating and managing projects, planning, product discovery…
- codebase-onboarding – Onboard a developer to a repository using Ontoly graph summaries. Use when asked to…
- competitor-summary-report-creator – Competitor Summary Report Creator. Use when working with competitor names or URLs and…
- linkedin-content – Use when someone wants to write, edit, or lint a LinkedIn post — a story, how-to…
- linkedin-skills – Use when someone wants to grow an organic LinkedIn presence — a content strategy for a…