neu_proc.ops.dust

Remove small disconnected specks: dust().

Dusting is per connected component, not per label: a 1-voxel speck carrying the same id as a large body elsewhere is removed while the body stays. That suits segmentations whose bodies are genuinely fragmented (one measured 344 components at scale 1, most of them single-voxel specks). Dropping small labels would be a different operation, and should get a different name.

There is no GPU path: cupyx.scipy.ndimage.label works on a binary mask, so touching bodies would merge into one component and a small body next to a large one would survive. For a binary input the mask is the labelling, so a GPU version would be correct there.

exclude_boundary spares a component that touches a face of the array, because within a crop its size is only a lower bound. The test is per component: keying it on the label instead would also spare every interior speck sharing an id with something on a face (34% of the interior dust on one 364^3 ground-truth crop).

Functions

dust(arr[, min_voxels, max_voxels, connectivity, ...])

Drop connected components outside the given voxel-count range.

Module Contents

neu_proc.ops.dust.dust(arr, min_voxels: int | None = None, *, max_voxels: int | None = None, connectivity: int = 6, invert: bool = False, exclude_boundary: bool = False, **kwargs)

Drop connected components outside the given voxel-count range.

dust(labels, 10) # remove anything under 10 voxels dust(labels, 10, invert=True) # keep ONLY those — what you are throwing away dust(labels, 5, max_voxels=50) # keep the band, dropping both tails

min_voxels keeps components of at least that many voxels. With max_voxels, larger components are dropped too, keeping only the band between. invert keeps only what would be removed, to inspect it first.

Thresholds are voxel counts. To start from a physical volume, convert with volume_to_voxels(), which divides by the product of the voxel sizes.

connectivity is 6 (face neighbours) by default; 26 joins corner-touching voxels, so fewer specks count as separate and fewer are removed.

exclude_boundary spares every component that touches a face of the array, however small; interior components are judged normally.

Runs on the CPU; a GPU array is copied off and back with a warning.