Skip to content
Back to skills

Dicom Ipp Z Slice Sort

ASecurity

Order DICOM slices into a coherent 3D volume by sorting on ImagePositionPatient[2] (the Z coordinate in patient space), with a filename-integer fallback for series whose tag is missing — never trust filename alphabetical order, never trust InstanceNumber

  • 61 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 12, 2026
toolspythonrust

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill dicom-ipp-z-slice-sort --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dicom Ipp Z Slice Sort?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dicom Ipp Z Slice Sort
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-dicom-ipp-z-slice-sort/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-dicom-ipp-z-slice-sort)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cv-dicom-ipp-z-slice-sort
description: Order DICOM slices into a coherent 3D volume by sorting on ImagePositionPatient[2] (the Z coordinate in patient space), with a filename-integer fallback for series whose tag is missing — never trust filename alphabetical order, never trust InstanceNumber
---

## Overview

DICOM filenames in a CT series are not guaranteed to be in anatomical order. Different scanners, anonymizers, and export tools produce wildly inconsistent name schemes — `1.dcm` may be the topmost slice on one study and the bottommost on the next. `InstanceNumber` is also unreliable: it can be reset, missing, or assigned in scan order rather than spatial order. The single trustworthy ordering is `ImagePositionPatient[2]`, the Z coordinate of the slice in patient space — sort by it ascending and you get a consistent head→feet (or feet→head, fix later) volume regardless of vendor. Keep an integer-filename fallback for the few exports that strip the tag entirely.

## Quick Start

```python
import pydicom
from os import listdir

def load_scans(dcm_dir):
    files = listdir(dcm_dir)
    try:
        slices = [pydicom.dcmread(f'{dcm_dir}/{f}') for f in files]
        slices.sort(key=lambda s: float(s.ImagePositionPatient[2]))
    except (AttributeError, KeyError):
        # fallback: integer-filename order when IPP tag is missing
        nums = sorted(int(f.split('.')[0]) for f in files)
        slices = [pydicom.dcmread(f'{dcm_dir}/{n}.dcm') for n in nums]
    return slices
```

## Workflow

1. List every `.dcm` file in the series directory
2. Read each with `pydicom.dcmread` and key the sort on `float(ds.ImagePositionPatient[2])`
3. Wrap in `try/except (AttributeError, KeyError)` to catch the rare missing-tag series
4. In the fallback branch, sort by the integer extracted from the filename stem
5. Stack `pixel_array`s in the resulting order and apply RescaleSlope/Intercept to get HU

## Key Decisions

- **`ImagePositionPatient[2]`, not `[0]` or `[1]`**: index 2 is the through-plane axis (Z) for axial CT; the other indices are in-plane translation and are constant across slices.
- **Sort ascending, flip later**: produces deterministic ordering; canonical head→feet flip can be done as a separate step (see `cv-ct-z-stack-orientation-flip`).
- **Integer-filename fallback, not lexicographic**: `'10.dcm'` sorts before `'2.dcm'` lexicographically; integer parsing fixes it.
- **`float()` cast required**: pydicom returns the position as `DSfloat` which is a string-ish type and won't compare correctly without the cast.
- **Keep the slice objects together with the position**: don't reorder a separate position array independently of the pixel arrays — index drift bugs are silent and brutal.

## References

- [Pulmonary Dicom Preprocessing](https://www.kaggle.com/competitions/rsna-str-pulmonary-embolism-detection)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…