spacr.qt.mask_engine

Pure-Python backend for the Qt make-masks screen.

Mirrors the image + mask I/O and label-mutation helpers from spacr.gui_elements.ModifyMaskApp, without touching Tk. The Qt screen above this reads/writes self.image and self.mask directly and calls these helpers for the non-brush operations (fill / relabel / invert / remove small).

Module Contents

spacr.qt.mask_engine.IMAGE_EXTS = ('.png', '.jpg', '.jpeg', '.tif', '.tiff', '.bmp')[source]
spacr.qt.mask_engine.list_images(folder: str) List[str][source]

Return filenames of image files in folder, sorted, or [].

spacr.qt.mask_engine.load_image_and_mask(folder: str, filename: str) Tuple[numpy.ndarray, numpy.ndarray][source]

Load an image and its accompanying mask (from folder/masks/).

  • Multi-channel images are collapsed to grayscale via BT.601 weights.

  • Missing masks are created as zeros of the image shape.

  • Both are returned as uint16 / uint8 arrays (image / mask).

spacr.qt.mask_engine.save_mask(folder: str, filename: str, mask: numpy.ndarray) str[source]

Relabel connected components and write to <folder>/masks/<name>.tif.

Returns the absolute save path.

spacr.qt.mask_engine.normalize_uint16(image: numpy.ndarray, lower_pct: float = 1.0, upper_pct: float = 99.9) numpy.ndarray[source]

Return image clipped + rescaled to its dtype’s full range.

spacr.qt.mask_engine.overlay_mask(image: numpy.ndarray, mask: numpy.ndarray, alpha: float = 0.5) numpy.ndarray[source]

Blend a colorized label mask onto a grayscale image, uint8 RGB.

spacr.qt.mask_engine.paint_disk(mask: numpy.ndarray, cx: int, cy: int, radius: int, value: int = 255) None[source]

In-place stamp a filled square (radius half-width) at (cx, cy).

spacr.qt.mask_engine.paint_line(mask: numpy.ndarray, x0: int, y0: int, x1: int, y1: int, radius: int, value: int = 255) None[source]

In-place stamp a line of disks between two points (Bresenham).

spacr.qt.mask_engine.fill_holes(mask: numpy.ndarray) numpy.ndarray[source]

Fill holes inside True regions; returns a relabeled mask.

spacr.qt.mask_engine.relabel_objects(mask: numpy.ndarray) numpy.ndarray[source]

Return a mask whose connected components are labeled 1..N.

spacr.qt.mask_engine.clear_mask(mask: numpy.ndarray) numpy.ndarray[source]

Return an all-zero array shaped like mask.

spacr.qt.mask_engine.invert_mask(mask: numpy.ndarray) numpy.ndarray[source]

Return the mask with foreground/background flipped and relabeled.

spacr.qt.mask_engine.remove_small_objects(mask: numpy.ndarray, min_area: int) numpy.ndarray[source]

Drop connected components with area < min_area (in pixels).

spacr.qt.mask_engine.erase_object_at(mask: numpy.ndarray, x: int, y: int) numpy.ndarray[source]

Zero out the object under (x, y). No-op if no object there.

spacr.qt.mask_engine.magic_wand(image: numpy.ndarray, mask: numpy.ndarray, seed_x: int, seed_y: int, tolerance: float, max_pixels: int = 100000, action: str = 'add') numpy.ndarray[source]

BFS flood-fill from (seed_x, seed_y) filling pixels whose intensity is within tolerance (L2 distance) of the seed. Writes 255 (add) or 0 (erase) into the returned mask copy.

class spacr.qt.mask_engine.MaskHistory(capacity: int = 20)[source]

Bounded undo/redo stack of mask arrays. Deep-copies on push so callers can mutate in place without corrupting older snapshots.

capacity[source]
clear() None[source]

Discard every snapshot from both the undo and redo stacks.

push(mask: numpy.ndarray) None[source]

Store a deep-copy of mask and drop any redo history.

can_undo() bool[source]

Return True when at least one prior snapshot is available to undo to.

can_redo() bool[source]

Return True when the redo stack has a snapshot to restore.

undo() numpy.ndarray | None[source]

Pop the top snapshot, save it to the redo stack, and return the previous snapshot (i.e. one step back). None if not possible.

redo() numpy.ndarray | None[source]

Restore the most-recently-undone snapshot, or None if empty.