Nitsor journal. nitsor.com/blog/industrial-ct-annotation-workflow. 27 Sep 2026.

Nitsor journal

Industrial CT annotation: prepare component labels for machine learning

Agree what each label marks before annotation starts. This public airframe scan shows the checks needed to prepare published part labels for training.

RSS feed
Slice 300 of the airframe scan: a pressure bottle, a stringer and frames, each part outlined in white with its published ID.A frame junction, a small ring and the edge of the pressure bottle in the airframe scan, each part traced by its published outline.
Real industrial CT with its published part outlines, Gruber et al., Fraunhofer EZRT, CC BY 4.0 (opens in a new tab), modified. Sources

Decide what each label means

An industrial CT annotation project starts with a decision about what each mark means. A pressure bottle, a pore and a crack are different targets. Each needs its own instructions, its own examples and its own review criteria.

A model trained to find components cannot be judged as if those components were defects. An inspector reviewing the labels also has to know whether an outline follows a material boundary, one physical object, or a region someone flagged for a closer look.

This guide follows one published volume through those choices: a section of a Me 163 airframe, scanned by Fraunhofer EZRT and released with instance labels for its parts.1 The picture at the top of this guide shows each part outlined in white. On a wide screen it is slice 300, with each part numbered by its published ID.

Class and instance, in plain words

A class says what an object is, such as pressure bottle. An instance ID says which one, so two bottles in one scan stay two objects. On slice 300, parts 19, 138, 139, 140, 146, 148 cross the slice, and instance 138 is the pressure bottle.

Component instances, materials and defects

For component work, decide whether the task needs one class for every bottle or a separate identity for each physical object. The V5 labels do the second. Instance 138 is the pressure bottle, and the parts around it on the same slice carry their own IDs. When an inspector corrects the edge of 138 on one slice, the neighbouring parts stay as they were.

Defect labelling needs a different instruction set. Say which observations belong to the class, how to treat a boundary nobody can place with confidence, and when to send a case to a second reader. A dark region in a reconstruction needs an interpretation before it becomes a porosity label, and your inspection authority writes that interpretation.

Write the exclusions as carefully as the positive examples. If the task is cracks, say how the team treats interfaces, reconstruction streaks and features that look like cracks. Then keep the class list with the labels. If a definition changes halfway through, the earlier labels still have to be read under the rules that produced them.

Check the volume before anyone draws

Before the first label, confirm what the volume is. This one is 512 slices of 512 by 512 samples. A pixel is 0.33 mm across in the plane of the slice, and the slices are 0.6 mm apart, so a voxel is almost twice as deep as it is wide.

Where 521 mm² comes from

Instance 138 covers 4,787 pixels on slice 300. At 0.33 by 0.33 mm a pixel, that is 521 mm². It is derived from the published label, not measured on the part.2

A distance drawn across slices and the same distance drawn within one slice cover different numbers of voxels. A tool that counts pixels without using the recorded spacing will give the wrong physical distance. Check that your measurement tool uses the scan's voxel spacing.

Record three more things with the task: how the volume was reconstructed, which window the annotators view it in, and the direction the slices run. A label drawn under one display window can look shifted under another, even though no voxel moved.

Review labels in their 3D context

A part that looks clean on one slice can merge with its neighbour two slices later. Review each label in linked views, axial, coronal and sagittal together, so the inspector follows the object through the volume instead of judging a single cut.

Give the inspector the context the annotator had: the class definition, the instance ID and the revision under review. In the 3D workspace, a reviewer accepts, corrects or rejects each annotation row. Each verdict binds the annotation hash it judged. The reviewer sees who authored each annotation, and finishing the review writes a commit under the reviewer's name. Verdicts remain in the history. Closing a review with a standing rejection requires a reason. The rejected work can be sent back with the reviewer's note, and corrections follow the configured workflow.

What a verdict is

A reviewer's accept, correct or reject per annotation row. Nitsor binds each verdict to the annotation hash the reviewer judged.

For defect work, the review records who judged each label and which annotation hash they saw. Your quality authority decides whether a part passes inspection.

An axial slice of a real industrial CT scan of an airframe section: frames, a stringer and a bracket, each traced by its published outline.
Real scan

An axial slice of the same airframe section with the dataset's published part outlines in white. Real industrial CT, Gruber et al., Fraunhofer EZRT, CC BY 4.0 (opens in a new tab), modified: windowed and rendered by Nitsor.

Keep model proposals apart from accepted work

Model proposals give annotators a mask to inspect and edit. Record whether each training label was drawn by a person, produced by a model or corrected by a person.

In Nitsor, SAM 2.1 takes points or a human-drawn box as a prompt on one slice and propagates the mask within a window of at most 64 slices.3 Each proposal records its model provenance. A person accepts or corrects it in the editor, and a corrected proposal is shown as corrected. A model cannot review a person's work.

Model provenance, in plain words

The record of the model that produced a proposal. Nitsor includes provenance in the annotation hash and keeps model-authored content identifiable.

Store the proposal, the correction and the final label as three separate records. If a training run later behaves oddly around one part, you can see whether its label came from a person, from a model, or from a person editing a model. Model proposals explains the workflow, and routed review sends uncertain proposals to an expert by a threshold or a sampling rule.

Fix the training set before the experiment

Labelling does not stop when the first model trains. Inspectors keep correcting edges and adding parts. If the training job reads a folder, it reads whatever the folder holds on the day it runs.

A Dataset Version freezes a selection at one commit into a manifest. The taxonomy in force is hashed into annotation commits. The training job pins the version by its ID and manifest hash, and later edits do not change it. Keep both values with the model artefact so the team can identify its training data. Dataset versioning shows how the version is made and read.

Decide the selection rule before the experiment. Include only accepted work, or say plainly that proposals are in the set. Keep every scan of one physical part in the same split, so a model is never tested on an object it has already trained on.

An intake checklist for industrial CT labels

Copy this list into your annotation instructions and fill it in before anyone draws. It works for component labels and for defect labels, with different answers.

  1. Name each class and say whether it needs instance IDs.
  2. Write one positive example and one exclusion per class.
  3. Record the voxel spacing, reconstruction and display window with the task.
  4. Say who reviews, in which views, and what a rejection needs as a reason.
  5. Keep model proposals, corrections and accepted labels as separate records.
  6. Choose the selection rule for the training set before the first run.
  7. Keep every scan of one physical part in the same split.
  8. Pin the training job to a Dataset Version ID and manifest hash.

We can walk through this checklist with your team on a public industrial CT volume. Request a walkthrough.

In the product: Industrial CTRead the annotation guide (opens in a new tab)

Notes and sources

  1. Gruber et al., Fraunhofer EZRT XXL-CT Instance Segmentation Me 163, subvolume V5. doi:10.5281/zenodo.10651746 (opens in a new tab), CC BY 4.0 (opens in a new tab). As held here: 512 slices of 512 by 512 samples, 0.33 mm per pixel in the plane of the slice, 0.6 mm between slices, with 169 published instance labels. Windowed and rendered by Nitsor. Back to text
  2. Area derived from the published instance 138 label on axial slice 300: 4,787 labelled pixels multiplied by 0.33 mm by 0.33 mm, rounded to 521 mm². Back to text
  3. SAM 2.1 is a segmentation model from Meta, released under Apache 2.0 (opens in a new tab). The 64-slice limit describes the propagation window Nitsor uses. The model proposals docs (opens in a new tab) describe the hosted job and its prompts. Back to text

Read next

Pictures: real clinical CT, Armato et al., "Data From LIDC-IDRI", TCIA, CC BY 3.0 (opens in a new tab), modified, with a SAM 2.1 proposal dashed, run by Nitsor outside the product; food X-ray CT, Schut et al., CWI and GREEFA, CC BY 4.0 (opens in a new tab), modified, with a SAM 2.1 proposal dashed, run by Nitsor outside the product. Sources

Show us what you inspect.

Start with a public CT or MRI scan. See how a model suggestion becomes a reviewed label and a fixed training dataset.