U

Ultimate Pydicom Framework

Boost productivity using this python, library, working, dicom. Includes structured workflows, validation checks, and reusable patterns for scientific.

SkillClipticsscientificv1.0.0MIT
0 views0 copies

Ultimate PyDICOM Framework

Read, modify, and create medical imaging DICOM files using pydicom. This skill covers DICOM file parsing, pixel data extraction, metadata manipulation, anonymization, and building medical image processing pipelines for radiology and pathology applications.

When to Use This Skill

Choose Ultimate PyDICOM Framework when you need to:

  • Read and parse DICOM files from CT, MRI, X-ray, or ultrasound modalities
  • Extract pixel data for image analysis or machine learning preprocessing
  • Anonymize patient information in DICOM files for research compliance
  • Create or modify DICOM metadata tags for data management

Consider alternatives when:

  • You need DICOM networking (C-STORE, C-FIND, C-MOVE) (use pynetdicom)
  • You need 3D medical image analysis with registration (use SimpleITK or ANTs)
  • You need deep learning on medical images specifically (use MONAI)

Quick Start

pip install pydicom numpy matplotlib
import pydicom import matplotlib.pyplot as plt # Read a DICOM file ds = pydicom.dcmread("ct_scan.dcm") # Access metadata print(f"Patient: {ds.PatientName}") print(f"Study: {ds.StudyDescription}") print(f"Modality: {ds.Modality}") print(f"Image size: {ds.Rows} x {ds.Columns}") print(f"Pixel spacing: {ds.PixelSpacing}") # Display pixel data pixel_array = ds.pixel_array plt.imshow(pixel_array, cmap="gray") plt.title(f"{ds.Modality}: {ds.SeriesDescription}") plt.colorbar(label="HU" if ds.Modality == "CT" else "Intensity") plt.savefig("dicom_image.png", dpi=150)

Core Concepts

DICOM Data Elements

TagKeywordDescription
(0010,0010)PatientNamePatient's full name
(0010,0020)PatientIDPatient identifier
(0008,0060)ModalityImaging modality (CT, MR, US)
(0028,0010)RowsImage height in pixels
(0028,0011)ColumnsImage width in pixels
(0028,0030)PixelSpacingPhysical pixel dimensions (mm)
(0020,0032)ImagePositionPatient3D position of image origin
(0028,1052)RescaleInterceptPixel value offset (for HU)
(0028,1053)RescaleSlopePixel value scale factor

CT Volume Reconstruction

import pydicom import numpy as np from pathlib import Path def load_ct_volume(directory): """Load and reconstruct a 3D CT volume from DICOM series.""" dicom_dir = Path(directory) slices = [] for dcm_file in sorted(dicom_dir.glob("*.dcm")): ds = pydicom.dcmread(str(dcm_file)) slices.append(ds) # Sort by ImagePositionPatient (z-coordinate) slices.sort(key=lambda s: float(s.ImagePositionPatient[2])) # Convert to Hounsfield Units volume = np.stack([s.pixel_array for s in slices]) slope = float(slices[0].RescaleSlope) intercept = float(slices[0].RescaleIntercept) volume_hu = volume * slope + intercept # Get physical dimensions pixel_spacing = [float(x) for x in slices[0].PixelSpacing] slice_thickness = float(slices[0].SliceThickness) spacing = [slice_thickness] + pixel_spacing print(f"Volume shape: {volume_hu.shape}") print(f"Voxel spacing: {spacing} mm") print(f"HU range: [{volume_hu.min():.0f}, {volume_hu.max():.0f}]") return volume_hu, spacing, slices[0] volume, spacing, ref_slice = load_ct_volume("./ct_series/")

DICOM Anonymization

import pydicom from pydicom.uid import generate_uid from datetime import datetime def anonymize_dicom(ds, new_patient_id="ANON001"): """Remove or replace patient-identifying information.""" # Tags to remove completely tags_to_remove = [ "PatientName", "PatientBirthDate", "PatientAddress", "PatientTelephoneNumbers", "ReferringPhysicianName", "InstitutionName", "InstitutionAddress", "PerformingPhysicianName", "OperatorsName" ] for tag in tags_to_remove: if hasattr(ds, tag): delattr(ds, tag) # Replace with anonymized values ds.PatientName = new_patient_id ds.PatientID = new_patient_id ds.StudyInstanceUID = generate_uid() ds.SeriesInstanceUID = generate_uid() ds.SOPInstanceUID = generate_uid() # Shift dates (preserve intervals but change absolute dates) if hasattr(ds, "StudyDate"): ds.StudyDate = "19000101" if hasattr(ds, "SeriesDate"): ds.SeriesDate = "19000101" return ds # Anonymize a file ds = pydicom.dcmread("patient_scan.dcm") ds_anon = anonymize_dicom(ds) ds_anon.save_as("anonymized_scan.dcm")

Configuration

ParameterDescriptionDefault
forceRead files without valid DICOM preamblefalse
stop_before_pixelsRead metadata only (skip pixel data)false
specific_tagsRead only specified tagsAll tags
transfer_syntaxPixel data encodingAuto-detected
apply_rescaleApply RescaleSlope/Intercept to pixelstrue
apply_voi_lutApply VOI lookup table for displayfalse

Best Practices

  1. Always apply RescaleSlope and RescaleIntercept for CT — Raw pixel values in CT DICOM files are stored values, not Hounsfield Units. Apply HU = pixel_value * RescaleSlope + RescaleIntercept to get physically meaningful values. Without this, windowing and thresholding produce wrong results.

  2. Sort slices by ImagePositionPatient, not filename — DICOM filenames have no guaranteed order. Sort by the z-coordinate of ImagePositionPatient to reconstruct volumes in the correct anatomical order. Filename sorting works sometimes but fails with some PACS exports.

  3. Use stop_before_pixels=True for metadata-only operations — When you only need to read tags (for querying, sorting, or anonymization), skip pixel data loading with pydicom.dcmread(path, stop_before_pixels=True). This is 10-100x faster for large image files.

  4. Handle compressed transfer syntaxes explicitly — DICOM files may use JPEG, JPEG2000, or RLE compression. Install pylibjpeg or gdcm to decode compressed pixel data. Attempting to read compressed files without the handler raises NotImplementedError.

  5. Validate UIDs after anonymization — After replacing StudyInstanceUID, SeriesInstanceUID, and SOPInstanceUID, verify that all files in a series share the same StudyInstanceUID and SeriesInstanceUID but have unique SOPInstanceUID. Inconsistent UIDs cause PACS import failures.

Common Issues

Pixel data appears inverted or wrong contrast — DICOM uses PhotometricInterpretation to indicate if pixel values represent light-on-dark or dark-on-light. Check ds.PhotometricInterpretation — if it's MONOCHROME1, invert the image: pixel_array = pixel_array.max() - pixel_array. MONOCHROME2 is the normal convention.

Cannot read compressed DICOM files — Error: NotImplementedError: no handler for transfer syntax. Install compression handlers: pip install pylibjpeg pylibjpeg-libjpeg pylibjpeg-openjpeg. For JPEG-LS, install gdcm. Check the transfer syntax with ds.file_meta.TransferSyntaxUID.

Missing tags in some DICOM files — Not all DICOM files contain all tags. Always check with hasattr(ds, 'TagName') or if 'TagName' in ds before accessing. Modality-specific tags (e.g., SliceThickness for CT) may be absent in other modalities. Use .get('TagName', default) for safer access.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates