pydicom

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.

By k-dense-ai · 1,425 installs

npx skills add k-dense-ai/scientific-agent-skills --skill pydicom

Source repository · Upstream listing

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): Uncompressed pixel arrays and image rendering: Install only the transfer syntax plugins required by the deployment: 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. Use: stop before pixels=True for 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=True only 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: 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: 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: 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: 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: 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 uses the same transform. The bundled renderer rejects functional group objects, Real World Value Mapping, unsupported photometric interpretations, and incomplete rescale pairs instead of silently using top level only transforms. Its min/max PNG/TIFF is a preview, not calibrated output, a spatially calibrated export, or a presentation state viewer. Compression, decompression, and encapsulation Accessing pixel array decodes 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() or encapsulate extended() for externally encoded frames. Read frames with current pydicom.encaps.generate frames() or get 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: Retain private elements only under an explicit reviewed safe private policy. Read [references/common tags.md](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. 1. Define purpose, recipients, linkage needs, regulations, threat model, and acceptable re identification risk. 2. 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). 3. Preserve source objects unchanged in controlled storage. 4. Apply every action recursively, including nested sequences. 5. Replace instance/reference UIDs consistently across the complete scope; preserve structural UIDs. 6. 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. 7. Inspect pixels, overlays, graphics, structured content, and recognizable visual features. Do not infer clean pixels from missing metadata or set BurnedInAnnotation=NO without verification. 8. Rebuild File Meta Information and preamble to prevent leakage. 9. 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 Run helper commands from skills/pydicom/ (or use the full script path); root must contain all inputs/outputs and output parent directories must already exist. All help paths are dependency free. The tools perform no network access and emit no DICOM values beyond narrow technical allowlists. Bundled content consists of the two linked references and documented helper scripts; synthetic tests live in the repository level tests/pydicom/ suite. The pydicom runtime dependency is installed from the pinned PyPI release. Path based snippets are illustrative until supplied with authorized local files; CLI tests use only generated synthetic data. The generated raw key file is a controlled local convenience and is created with owner only permissions. For production, materialize key bytes from an approved secret manager into a locked ephemeral file, restrict access to the de identification service, and securely remove it afterward. Store any optional UID map separately from derivatives; it directly links original and replacement identifiers. pydicom 3.0 migration notes read file() and write file() were removed; use dcmread() and dcmwrite() . write like original is deprecated; use enforce file format . pydicom.pixel data handlers is deprecated for removal in v4; use pydicom.pixels . Dataset.pixel array uses the new pixels backend by default and converts YCbCr to RGB when possible. JPEGLossless now means UID 1.2.840.10008.1.2.4.57 ; JPEGLosslessSV1 is .70 . Dataset.is little endian and is implicit VR are deprecated for v4. Verification scope Synthetic local fixtures exercise native decoding, signed pixels, rescale/VOI, presentation polarity, JSON, writer/UID