pydicom
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 / Use
npx skills add K-Dense-AI/scientific-agent-skills --skill pydicomInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
MarketingSupported Platforms
Our assessment of pydicom
pydicom scores 100/100 on our quality scale, 5th of 586 Marketing skills we index (top 1%).
Its SKILL.md is 16 KB long, well organised into 29 sections with 11 code examples: a thorough specification that gives an agent plenty to work with.
With 46,441 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated about 2 months ago, so pydicom is actively maintained.
- Our last check on 2026-10-22 found the source still online.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful.
AI review by kimi-k2.7-code on 2026-09-25. Automated pattern scan on 2026-09-25. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
pydicom compared with similar skills
pydicom has the highest quality score among these 4 similar skills, though 4 alternatives have been updated more recently.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| pydicom (this skill)by K-Dense-AI | 100 | 46.4k | 48d ago | SKILL.md |
| Agent-Reachby Panniantong | 100 | 110.3k | 1d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 79.1k | today | CLAUDE.md |
| Scraplingby D4Vinci | 100 | 99.8k | today | MCP Server |
| crawl4aiby unclecode | 100 | 87.1k | 4d ago | MCP Server |
Frequently asked questions
- How do I install pydicom?
- Run
npx skills add K-Dense-AI/scientific-agent-skills --skill pydicom. The install tabs above show the steps for each supported agent. - Which AI agents does pydicom work with?
- It is written for Zed, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is pydicom safe to use?
- Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful. It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is pydicom still maintained?
- The repository was last updated about 2 months ago, so pydicom is actively maintained.
Skill content
View source on GitHubname: pydicom description: Use pydicom to read, inspect, write, transform, and safely preflight local DICOM datasets and pixel data. Applies to DICOM metadata, transfer syntaxes, compression plugins, frames, private elements, JSON, and bounded de-identification review. license: MIT compatibility: Python 3.10+ with pydicom 3.0.2; optional pinned NumPy, Pillow, and pixel plugins. Helper CLIs are local-only and require authorized data. metadata: version: "1.2" skill-author: "K-Dense Inc." last-reviewed: "2026-07-23"
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, while the live DICOM Standard may be newer.
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 exact reviewed release:
uv pip install "pydicom==3.0.2"
Uncompressed pixel arrays and image rendering:
uv pip install "pydicom==3.0.2" "numpy==2.5.1" "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.1" "pylibjpeg==2.1.0" \
"pylibjpeg-libjpeg==2.4.0" "pylibjpeg-openjpeg==2.5.0" \
"pylibjpeg-rle==2.2.0"
# JPEG-LS encoder/decoder
uv pip install "numpy==2.5.1" "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
- Need an aggregate overview: run
scripts/extract_metadata.py. - Need bounded technical checks: run
scripts/dicom_inventory.py. - Need codec deployment preflight: run
scripts/transfer_syntax_inspector.py. - Need frame/memory planning: run
scripts/pixel_frame_planner.py. - Need one non-diagnostic rendered frame: run
scripts/dicom_to_image.py. - Need a pseudonymized derivative: read the de-identification section, create
a site-reviewed action profile, then run
scripts/anonymize_dicom.pyandscripts/deidentification_audit.py. - 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 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 YCbCr pixel data to RGB when possible; 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.
MONOCHROME1 may require presentation inversion. 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.
Compression, decompression, and encapsulation
- Accessing
pixel_arraydecodes as needed but does not change the dataset. Dataset.decompress()changes Pixel Data in place, sets Explicit VR Little Endian, updates image metadata, and generates a new SOP Instance UID by default.Dataset.compress(uid)changes Pixel Data and Transfer Syntax in place and generates a new SOP Instance UID by default.- pydicom 3.0 built-in/found encoders cover RLE Lossless, JPEG-LS, and JPEG 2000 combinations documented in the stable plugin matrix.
- Each compressed frame is separately encoded and then encapsulated. Use
encapsulate()orencapsulate_extended()for externally encoded frames. - Read frames with current
pydicom.encaps.generate_frames()orget_frame(); legacy encapsulation generator names are deprecated for pydicom 4.
Always inspect capabilities first, limit decoded bytes/frames, and verify pixel correctness independently. Lossy compression acceptability is outside pydicom and the DICOM encoding specification.
DICOM JSON and private elements
Dataset.to_json(), to_json_dict(), and Dataset.from_json() implement the
DICOM JSON Model, but pydicom documents JSON support as beta. Full JSON may
inline binary data and expose every identifier and pixel payload. Do not emit
it as a metadata report. A BulkDataURI handler introduces separate storage,
authorization, and retrieval obligations.
Private elements are not standardized and may contain PHI:
# Recursive removal, but not sufficient de-identification by itself.
ds.remove_private_tags()
Retain private elements only under an explicit reviewed safe-private policy. Read references/common_tags.md for tag access, privacy classes, and standard pointers.
De-identification workflow
DICOM PS3.15 Annex E explicitly states that confidentiality profiles do not guarantee removal of all identifying information and do not replace a complete de-identification process.
- Define purpose, recipients, linkage needs, regulations, threat model, and acceptable re-identification risk.
- Select the Basic Application Level Confidentiality Profile and needed options (pixel, recognizable visual features, graphics, structured content, descriptors, temporal information, patient characteristics, devices, institutions, UIDs, and safe private data).
- Preserve source objects unchanged in controlled storage.
- Apply every action recursively, including nested sequences.
- Replace instance/reference UIDs consistently across the complete scope; preserve structural UIDs.
- Decide date/time handling explicitly. A fixed shift can preserve intervals but partial dates, time zones, standalone times, leap days, longitudinal linkage, and external events require reviewed policy.
- Inspect pixels, overlays, graphics, structured content, and recognizable
visual features. Do not infer clean pixels from missing metadata or set
BurnedInAnnotation=NOwithout verification. - Rebuild File Meta Information and preamble to prevent leakage.
- Run technical validation and a de-identification audit, then perform expert verification and documented risk review.
The bundled script intentionally sets PatientIdentityRemoved to NO because
it cannot establish successful de-identification.
Helper CLIs
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
110.3kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
79.1kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
Scrapling
99.8k🕷️ The BEST Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
crawl4ai
87.1kOfficial Crawl4AI Cloud: a hosted web scraping, extraction, and search API for AI agents. Free API key, 1,000 credits a month, no card. Fully open source: this repo is the Apache-2.0 crawler that powers it, and you can self-host it.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
