itasc.cellpose.native_masks

Capture Cellpose-SAM native masks, Qt-free, for the standalone distro.

The app’s itasc.cellpose.cellpose_runner keeps only the probability / flow maps (_, flows, _ = model.eval(...)) because the integrated pipeline derives its labels from divergence maps + Ultrack. The independently-shipped itasc-cellpose tool instead wants the labelled masks Cellpose computes and the runner throws away — that is index 0 of model.eval.

This module re-runs the same eval loop but keeps the masks, producing a canonical (T, Z, Y, X) label stack per channel. It reuses the runner’s model loading, gamma correction and cancellation so the two paths stay consistent; it does not touch the runner itself, so the app’s behaviour is unchanged.

Functions

iter_nucleus_maps_stack(stack, params, *[, ...])

Yield per-frame (t, masks, prob, flow_rgb) so results stream into a viewer.

offset_slice_labels(slices)

Stack per-z 2D label images into (Z, Y, X) with frame-unique labels.

run_cell_masks_frame(frame, z, params)

Native cell masks for a single 2D z-slice.

run_cell_masks_stack(stack, params, *[, ...])

Process a (T, Z, Y, X) stack slice-by-slice into (T, Z, Y, X) labels.

run_nucleus_maps_frame(frame, z, params)

Native masks + sigmoid prob map + RGB flow for one 2D z-slice.

run_nucleus_masks_frame(frame, z, params)

Native nucleus masks for one frame.

run_nucleus_masks_stack(stack, params, *[, ...])

Process a (T, Z, Y, X) stack into a (T, Z, Y, X) label stack.

write_masks(masks_tzyx, output_dir, channel)

Write {channel}_masks.tif (int32, axes TZYX); return its path.

itasc.cellpose.native_masks.run_nucleus_masks_frame(frame, z, params)[source]

Native nucleus masks for one frame.

z is None runs full 3D over (Z, Y, X) and returns labels (Z, Y, X); an integer z runs 2D on frame[z] and returns labels (Y, X).

Return type:

ndarray

Parameters:
itasc.cellpose.native_masks.run_cell_masks_frame(frame, z, params)[source]

Native cell masks for a single 2D z-slice. Returns labels (Y, X).

Return type:

ndarray

Parameters:
itasc.cellpose.native_masks.run_nucleus_masks_stack(stack, params, *, progress_cb=None, cancel_cb=None)[source]

Process a (T, Z, Y, X) stack into a (T, Z, Y, X) label stack.

params.do_3d runs a coherent 3D segmentation per frame; otherwise each z-slice is segmented in 2D and the slices are stacked with frame-unique labels (see offset_slice_labels()).

Return type:

ndarray

Parameters:
itasc.cellpose.native_masks.run_cell_masks_stack(stack, params, *, progress_cb=None, cancel_cb=None)[source]

Process a (T, Z, Y, X) stack slice-by-slice into (T, Z, Y, X) labels.

Return type:

ndarray

Parameters:
itasc.cellpose.native_masks.run_nucleus_maps_frame(frame, z, params)[source]

Native masks + sigmoid prob map + RGB flow for one 2D z-slice.

A single model.eval pass yields (masks (Y, X) int32, prob (Y, X) float32, flow_rgb (Y, X, 3) uint8) — the labels plus the two intermediates (probability and flow) the standalone tool surfaces so Channel 1 can be tuned. The standalone anchor is always per-plane 2D, so z is an integer slice.

Return type:

tuple[ndarray, ndarray, ndarray]

Parameters:
itasc.cellpose.native_masks.iter_nucleus_maps_stack(stack, params, *, progress_cb=None, cancel_cb=None)[source]

Yield per-frame (t, masks, prob, flow_rgb) so results stream into a viewer.

For a (T, Z, Y, X) input each yield carries one time-frame: masks and prob are (Z, Y, X) and flow_rgb is (Z, Y, X, 3) uint8, with per-frame-unique mask labels (offset_slice_labels()). Always per-plane 2D (the standalone anchor never runs do_3d). A caller can drop each frame into a napari layer as it arrives instead of waiting for the whole stack.

Parameters:
itasc.cellpose.native_masks.write_masks(masks_tzyx, output_dir, channel)[source]

Write {channel}_masks.tif (int32, axes TZYX); return its path.

Return type:

Path

Parameters:
itasc.cellpose.native_masks.offset_slice_labels(slices)[source]

Stack per-z 2D label images into (Z, Y, X) with frame-unique labels.

Each 2D Cellpose run labels its objects from 1 independently, so naively stacking would collide labels across z. We offset every slice’s non-zero labels by the running maximum so a frame’s labels are globally unique; the background 0 is preserved. For the common single-z case this is a no-op.

Return type:

ndarray

Parameters:

slices (list[ndarray])