Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

dicom-converter

Convert medical DICOM images (CT, MRI, and more) into clear, high-contrast PNG pictures you can open anywhere — with the same detail a radiologist's viewer shows.


What is this?

Hospitals and imaging centers store scans in a special format called DICOM (Digital Imaging and Communications in Medicine). DICOM files are the "master copy" of a scan — like a film negative in photography. They hold far more data than a normal image: every pixel carries a precise measurement of tissue density, plus patient info and scan settings.

The catch: most programs can't open DICOM files. If you've ever been emailed a scan and had no way to look at it, this tool is for you.

dicom-converter is like a photo lab for medical images. It takes DICOM files and "develops" them into ordinary PNG pictures — the kind you can open in any browser, image viewer, or document. The output isn't just any picture: it applies the same brightness/contrast adjustments a radiologist's PACS viewer uses, so what you see is what a doctor would see.

Why convert?

Problem What this tool does
DICOM files won't open in normal programs Outputs universal PNG files
Raw DICOM data looks flat and washed-out Applies the medical "window" for strong, readable contrast
Small image formats lose fine detail Uses lossless PNG — no compression artifacts that could hide a lesion
Every pixel needs a physical meaning Embeds resolution (DPI) from the scan, so measurements stay meaningful

中文概览: 这个工具把医院的 DICOM 影像(如 CT 扫描)转换成普通 PNG 图片,方便任何人查看。转换时应用了和放射科医生查看器相同的窗口技术,输出高对比度、不损失细节的清晰图片。

How it works

 DICOM file ──► read (pydicom) ──► modality LUT ──► VOI window ──► PNG
 (16-bit tissue density)               │                │
                                       │        high-contrast grayscale
                                       │        (same math a PACS viewer uses)
                                       ▼
                              output/SE000006/IM000001.png

In plain words:

  1. Read — load the DICOM file with the pydicom library.
  2. Calibrate (modality LUT) — turn raw sensor numbers into meaningful tissue-density values (Hounsfield units for CT).
  3. Window (VOI) — pick the brightness range that makes soft tissue, bone, and air all clearly visible. This is the step that makes the image look "right."
  4. Save — write a lossless PNG, sized to match the scan and tagged with its physical resolution.

Quick start

Prerequisites

  • Python 3.13+
  • uv (a fast Python package manager) — install with curl -LsSf https://astral.sh/uv/install.sh | sh or brew install uv

Install and run

# 1. Install dependencies into a virtual environment
uv sync

# 2. Run the converter on a DICOM study directory
uv run python -m readme_processed.run

The tool looks for DICOM files under DICOM/PA000001/ST000001/ and writes pictures to output/, mirroring the scan's series structure:

output/
└── SE000006/
    ├── IM000001.png
    ├── IM000002.png
    └── ...

Open any .png in output/ to see the result.

Note on sample data: the example DICOM study is not committed to this repository (medical data stays out of git). Point the INPUT_ROOT constant in src/readme_processed/run.py at your own study, or add your files under DICOM/.

Output formats

Format Depth Lossless? Best for
png (default) 8-bit ✅ Yes Everyday viewing — sharp, high-contrast, opens everywhere
jpg 8-bit ❌ No Sharing where a smaller file matters (web/email)
png16 16-bit ✅ Yes Analysis that needs maximum tonal smoothness

The default is png: lossless, windowed for high contrast, and readable by any program.

To choose a format, edit FORMATS in src/readme_processed/run.py:

FORMATS = ("png",)          # default
FORMATS = ("jpg",)          # lossy, smaller files
FORMATS = ("png16",)        # 16-bit, maximum depth
FORMATS = ("jpg", "png16")  # write both

Or call the library directly:

from readme_processed.convert import convert_dicom_to_image

convert_dicom_to_image("scan.dcm", "output.png")              # default: 8-bit png
convert_dicom_to_image("scan.dcm", "output.png", fmt="png16")

Project structure

src/readme_processed/
├── convert.py   # Core: reads one DICOM file, applies LUT + windowing, saves an image
├── study.py     # Batch: walks a study directory, converts every image, reports counts
├── run.py       # Entry point: points at the input/output folders and formats
└── __init__.py  # Package wiring

tests/           # 58 tests: windowing math, formats, DPI, batch behavior, full-study smoke

Common commands

# Run the converter
uv run python -m readme_processed.run

# Run the test suite (58 tests)
uv run pytest

# Lint
uvx ruff check src tests

# Type-check
uvx mypy src tests

FAQ

Why do the images look so much better than opening the raw file? Raw DICOM data spans a huge brightness range (thousands of levels) that looks flat gray to human eyes. The tool applies the medical "window" (Window Center/Width) — the exact adjustment a radiologist's PACS viewer uses — so soft tissue, lung, and bone each get their own contrast. Every series carries its own window, just like in the viewer.

Where is the example data? The DICOM study is gitignored (medical data shouldn't live in a repository). Point INPUT_ROOT in run.py at your own study, or drop files under DICOM/. The tests use synthetic DICOM fixtures, so the suite runs without any patient data.

How do I get 16-bit output? Use FORMATS = ("png16",) in run.py, pass fmt="png16" to convert_dicom_to_image, or set EXPORT_ALL_FORMATS = True to write jpg + png16 alongside.

Why PNG instead of JPG? JPG is "lossy" — it discards fine detail that can look like noise or even mimic a small lesion. PNG is lossless: every pixel is preserved exactly. For medical review, lossless is the safe choice.

How does the tool know what contrast to use? The DICOM file itself carries the answer: the Window Center and Window Width tags that the scanner (or a radiologist) chose. The tool reads these and applies them, so output matches clinical viewing. If a scan has no window, the tool falls back to normalizing the full range.


Built with pydicom, Pillow, and NumPy.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages