Mirobody
인간 건강의 표준 레지스트리, 약 2천 개 임상·생활 지표를 하나의 언어로 정리
Enterprise medical-imaging pipeline: ingest, de-identify, QC, and convert DICOM for 3D Slicer and ITK-SNAP
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A medical-imaging research pipeline that prepares DICOM for 3D Slicer and ITK-SNAP.
dicom-forge takes a folder of DICOM, refuses series whose metadata signals burned-in pixel text, de-identifies the headers (names, IDs, private tags, UIDs), runs quality control, and converts it into formats clinical-research viewers load natively — NIfTI (.nii.gz), NRRD (.nrrd), and Slicer's segmentation format (.seg.nrrd). Every run produces a serialisable audit record.
It is the headless core of a two-repo system; its companion, slicer-forge, wraps it in a 3D Slicer extension GUI.
📌 New here? Read the project showcase for the big picture — the problem, the architecture, who it's for, and the engineering highlights.
Real imaging pipelines separate a testable, headless core from a thin GUI. 3D Slicer itself is built this way: ITK/VTK do the work, the GUI is a shell on top. dicom-forge is that core — so the logic is unit-tested in CI without needing Slicer installed, and the same code runs from the command line, from Python, or inside Slicer's Python console.
PatientID and UIDs use keyed HMAC pseudonyms under a private project secret. Series whose metadata signals burned-in pixel text are rejected by default..seg.nrrd label maps with named, coloured segments.py.typed, strict mypy.dicomforge) and a clean Python API.dicom-probe, reads a series through ITK's own GDCM path (the engine under Slicer/ITK-SNAP) and reports the true volume geometry as JSON.pip install dicom-anvil # core (ingest, de-id, QC)
pip install "dicom-anvil[convert]" # + SimpleITK/pynrrd/nibabel for conversion
Names: the package installs as
dicom-anvil(the PyPI namedicom-forgewas already taken) and imports asdicomforge; the repository staysdicom-forge.
The conversion stack (SimpleITK et al.) is an optional extra so the core stays lightweight and CI-friendly. Calling a conversion function without it raises a clear
MissingDependencyErrortelling you exactly what to install.
# List the series in a folder
dicomforge inspect ./study
# Run QC and print a report
dicomforge qc ./study
# A private per-project secret keeps pseudonyms stable across runs (never commit it)
export DICOMFORGE_PSEUDONYM_SECRET="<from your secrets manager>"
# Full pipeline: burned-in check -> de-identify -> QC -> convert to Slicer NRRD
dicomforge convert ./study ./out/case01 --format nrrd --deid-level moderate
from dicomforge import run_pipeline, PipelineConfig, OutputFormat
result = run_pipeline(
"./study",
"./out/case01",
config=PipelineConfig(output_format=OutputFormat.NRRD),
)
print(result.qc.passed) # True / False
print(result.pixel_privacy.status) # "unverified" (never "clean"): pixels are not analysed
print(result.conversion.output_path) # ./out/case01.nrrd
print(result.model_dump_json(indent=2)) # full audit record
ingest ──> burned-in check ──> de-identify ──> QC ──> convert
Series flagged for burned-in pixel annotation are rejected before anything is written. Header de-identification runs in memory before conversion — your source DICOM is never modified. NRRD/NIfTI outputs carry no DICOM header fields, but their voxels are the source pixels, unchanged.
⚠️ Not a validated anonymization tool. De-identification is header-only risk reduction. There is no HIPAA, GDPR or other regulatory claim, and no clinical validation. Pixel data is never analysed: burned-in text is caught only when metadata signals it. Free-text screening finds only the record's own identifiers, and some quasi-identifiers (age, sex; dates at
basic) are kept by design. Read the de-identification policy and review output before it leaves a controlled environment.
python -m venv .venv && . .venv/Scripts/activate # Windows
pip install -e ".[dev,convert]"
pytest # run the suite (synthetic DICOM, no real data needed)
ruff check . && mypy # lint + type-check
PolyForm Noncommercial License 1.0.0 © Angela Hudson
Noncommercial use — personal, research, educational, and other noncommercial purposes as defined by the license — is free. Any commercial use requires a separate license from the copyright holder. See LICENSE for the full terms, or open an issue to ask about commercial licensing.