DICOM annotation workflow: check slice order, spacing and mask alignment
Before anyone draws on a DICOM series, confirm which volume is on screen and where each slice sits in space. A public chest CT shows what goes wrong otherwise.

Identify the series and its geometry
Before an annotator draws on a DICOM series, the team needs to know which volume is on screen and how its slices relate to physical space.
One stack of images from one acquisition. A study can hold several series, such as a thin and a thick reconstruction of the same scan.
A readable image is only the start of that check. Slice identity, spacing and orientation have to stay consistent as the data moves through preparation, annotation and training. If they drift, a mask can look right in one view and sit in the wrong place in another.
Begin with one identified series. Record its identifier, the number of slices, the image size, the pixel spacing, the orientation and the position of every slice. Keep the source files where the report can be checked against them. The report below is that record for the case in this guide, LIDC-IDRI-0003, a public chest CT.1
Notice that the in-plane spacing and the slice spacing differ by a factor of three. A pixel is 0.820 mm across, and the next slice is 2.5 mm away. Any measurement that crosses slices has to use both numbers. A screenshot carries neither, so keep the geometry beside any figure, mask or measurement taken from it.
Series: LIDC-IDRI-0003, one axial chest CT series
Slices: 140, each 512 by 512 pixels
Pixel spacing: 0.820 by 0.820 mm, so the slice is 420 mm across
Slice spacing: 2.5 mm between positions, 2.5 mm thick
First image position: x -228.8, y -210.0, z -379.0 mm
Positions covered: z -379.0 to -31.5 mm
Sorted by: z ascending, so array index 0 is the lowest slice
InstanceNumber: runs the other way: InstanceNumber = 140 minus indexSort by position, not by number
A file name, an InstanceNumber and an array index can follow three different orders. In this series, the slice the header calls InstanceNumber 64 is index 76 once the slices are sorted by position, and it sits at z -189.0 mm. All three name the same image.
The scanner numbered the images from the head down. Sorting by position puts the lowest slice first. Neither is wrong; they are two conventions.
InstanceNumber is a label the scanner writes. It usually counts in acquisition order, but nothing requires it to match position, and some series skip or repeat numbers. Build the volume from ImagePositionPatient and ImageOrientationPatient instead: project each position onto the slice normal and sort by that distance. Then check the gaps. In this series every step is 2.5 mm, so a missing or doubled slice shows up as a step of 5 mm or 0.
Write the mapping down with the task. A caption that says slice 64 is ambiguous the moment someone opens the data in a different reader. A caption that says InstanceNumber 64, index 76, z -189.0 mm can be checked by anyone.
| Convention | This slice |
|---|---|
| InstanceNumber in the header | 64 |
| Index in the array sorted by position | 76 |
| Position along the patient axis | z -189.0 mm |
Readers' outlines: InstanceNumber 61 to 70
Index 64z -219.0 mmwhere a script puts it
Index 76InstanceNumber 64z -189.0 mm
30 mm: 12 slices at 2.5 mm
Index 0InstanceNumber 140z -379.0 mm
Index 139InstanceNumber 1z -31.5 mm
Figure 1. One series, sorted by position
The 140 slices of LIDC-IDRI-0003 in order of z, lowest first. InstanceNumber counts the other way, so InstanceNumber 64 is index 76. A mask placed at index 64 lands 12 slices lower. Ticks every 10 slices (25 mm). Positions and numbers are read from the series headers.
Confirm that masks align with the volume
Label files carry their own slice references, and those references can use either convention. In this case the four radiologists outlined one nodule. Readers 1, 2 and 3 marked it on InstanceNumber 62 to 68; reader 4 on 61 to 70.2
Now suppose a conversion script places the outline for InstanceNumber 64 at array index 64. It lands 12 slices away, 30 mm lower in the chest, on tissue that has nothing to do with the nodule. The mask's shape alone does not reveal that it sits on the wrong slice.
Index 64 sits at z -219.0 mm and index 76 at z -189.0 mm: 12 slices at 2.5 mm apart.
Two checks catch it. First, compare each label's slice reference with the geometry report, by position, not by number. Second, look at the label in another plane. In a coronal or sagittal view, a mask that jumped 12 slices breaks away from the structure it should follow. Figure 2 shows that plane for this series: the whole volume opened on a coronal plane through the nodule.
In the 3D workspace, the source viewer links axial, coronal and sagittal views at the same position. Compare those planes when checking whether a label follows the structure it should.

Figure 2. The same series in a second plane
All 140 slices rebuilt as one volume. A coronal plane moves from the front of the chest back to the nodule, the small bright spot in the left lung, and holds there. The camera is fixed and nothing turns. No label is drawn: the figure shows the plane a reviewer checks a mask in.
Real clinical CT, Armato et al., "Data From LIDC-IDRI", TCIA, CC BY 3.0 (opens in a new tab), modified: rebuilt and rendered by Nitsor. Sources
Check the formats your workflow uses
DICOM covers many encodings. Before a project starts, list the transfer syntaxes your files use and confirm the tool opens each one as a volume, not only as separate images. Test with real files from the scanner you will use, including the awkward ones: a series with a gap, a series exported twice, a scout image mixed into the stack.
Uncompressed DICOM Part 10 and VGStudio .vgi/.vol open as volumes in Nitsor. Geometry, slice-order and duplicate-instance checks report named issue codes. Storage and formats describes storage connections and supported formats.
Recording a scan as a source in Nitsor. This is separate from aligning two images.
Separate human outlines from model output
The same slice can carry labels from very different sources. For this case we also ran TotalSegmentator, a public model for anatomy, outside Nitsor. On slice 64 it labels lung lobes, ribs, the heart and the aorta, 27 structures in all.3 It does not outline the nodule, because the nodule is not one of its classes.
Keep those sources apart in the record. The radiologists' outlines are published human annotations of a finding. The lobe masks are model proposals of anatomy. A lobe prediction is not a reference outline for anything the readers drew, and a training set has to say which kind of label each member is.
In Nitsor, each proposal records its model provenance, and a person accepts or corrects it in the editor. Corrected proposals stay identifiable as corrected. Save the intake result with the task as well, so the reviewer can see which series was checked and which label sources belong to it. CT and MRI labels for research shows the full workflow for imaging teams.
A DICOM intake checklist
Run this once per series before the first label, and keep the result with the task. The geometry report above is a completed example.
- Record the series identifier, slice count and image size.
- Record pixel spacing, slice spacing and slice thickness separately.
- Sort slices by position along the slice normal, not by InstanceNumber.
- Check every gap between positions, and flag missing or doubled slices.
- Write the InstanceNumber, index and position mapping into the task.
- List the transfer syntaxes and confirm each opens as a volume.
- Check each label's slice reference against the positions.
- Look at every label in a second plane before accepting it.
- Mark each label as a human annotation or a model proposal.
We can walk through these geometry checks with your team on a public DICOM series. Request a walkthrough.
In the product: 3D workspaceRead the annotation guide (opens in a new tab)
Notes and sources
- Armato et al., "Data From LIDC-IDRI", The Cancer Imaging Archive, doi:10.7937/K9/TCIA.2015.LO9QL9SX (opens in a new tab), CC BY 3.0 (opens in a new tab). Case LIDC-IDRI-0003, read from the series headers on 27 September 2026. Windowed and rendered by Nitsor. Back to text
- Slice references from the readers' published annotation file for this case. In every outline, InstanceNumber plus array index is 140. Back to text
- TotalSegmentator v2.18.0, task total, run by Nitsor outside the product on 27 September 2026. Its output is a model proposal, not a published label. Back to text

