Skip to content

Mask painter: per-class paint mode (filled vs. outline) and per-class visibility toggle #83

@yulewu

Description

@yulewu

Summary

The current mask painter renders all cell masks exclusively as outlines. This feature request adds two related enhancements to the mask painter panel: (1) per-class paint mode — each cell class can be configured to render as either an outline or a filled (semi-transparent) polygon; (2) per-class visibility toggle — individual cell classes can be shown or hidden without affecting other classes. Together these allow users to highlight a cell type of interest as a filled overlay on top of the intensity image, while suppressing unimportant classes entirely.


Motivation / Use Case

When reviewing MIBI images it is common to want to visually inspect whether a classifier correctly identified a cell type of interest. The current outline-only rendering makes it difficult to spot small or densely packed cells. A filled semi-transparent overlay makes the spatial distribution of a class immediately legible against the raw intensity image underneath, and hiding unrelated classes at the same time reduces visual clutter.


Proposed UI Changes

In the mask painter panel (currently driven by mask_color_overlay.py + palette_store.py + ui_components.py), add a row of controls per cell class:

Control Behavior
Visibility checkbox / eye icon Show / hide all cells of this class; unchecking removes them from the rendered overlay entirely
Paint mode toggle Two-state toggle: outline (current behavior) / filled (flood-fills the cell polygon at the class color with configurable alpha)
Opacity / alpha slider (optional) When filled mode is active, controls transparency (e.g. 0–100 %)

The existing per-class color picker and the overall mask opacity slider should remain unchanged.


Proposed Implementation Notes

  • palette_store.py — extend the per-class state dict to include visible: bool and paint_mode: Literal["outline", "filled"] (plus an optional fill_alpha: float). Defaults: visible=True, paint_mode="outline" to preserve backward compatibility.
  • mask_color_overlay.py — update the compositing logic to branch on paint_mode: "outline" keeps the existing find_boundaries-based path; "filled" draws the full cell mask region at fill_alpha and optionally draws the boundary on top so cells remain distinguishable. Respect the visible flag by skipping the class entirely during compositing.
  • ui_components.py — add the eye-icon toggle and paint-mode button next to the existing color picker for each class row in the mask painter widget.
  • main_viewer.py — wire the new per-class state to the overlay re-render callback (same pattern as the existing color-change observer).

Acceptance Criteria

  • Each class row in the mask painter panel has a visibility toggle; unchecking hides that class from the image without affecting any other class.
  • Each class row has an outline/filled toggle; switching to "filled" renders the class as a semi-transparent color flood over the full cell area.
  • Filled mode is visually distinguishable from outline mode at the default alpha (suggested: ~0.35).
  • Default state (outline, visible=True) exactly reproduces current behavior — no regressions.
  • Unit test in tests/ covers palette_store serialization of the new fields and the compositing branch in mask_color_overlay.

Related Files

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request
No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions