napari_track_edit.data_views.views.layers.contour_labels
Classes
Extended labels layer that allows to show contours and filled labels simultaneously |
Functions
|
|
|
|
|
Computes the contours of a 2D label image. |
Module Contents
- napari_track_edit.data_views.views.layers.contour_labels.left_only_draw(layer, event)
- napari_track_edit.data_views.views.layers.contour_labels.left_only_pick(layer, event)
- napari_track_edit.data_views.views.layers.contour_labels.get_contours(labels: numpy.ndarray, thickness: int, background_label: int, filled_labels: list[int] | None = None)
Computes the contours of a 2D label image.
- Parameters:
labels (array of integers) – An input labels image.
thickness (int) – It controls the thickness of the inner boundaries. The outside thickness is always 1. The final thickness of the contours will be thickness + 1.
background_label (int) – That label is used to fill everything outside the boundaries.
- Return type:
A new label image in which only the boundaries of the input image are kept.
- class napari_track_edit.data_views.views.layers.contour_labels.ContourLabels(data: numpy.array, name: str, opacity: float, scale: tuple, colormap: napari.utils.DirectLabelColormap)
Bases:
napari.layers.LabelsExtended labels layer that allows to show contours and filled labels simultaneously
- property _type_string: str
- _filled_labels = []
- property filled_labels: list[int] | None
List of labels in a group
- _calculate_contour(labels: numpy.ndarray, data_slice: tuple[slice, ...]) numpy.ndarray | None
Calculate the contour of a given label array within the specified data slice.
- Parameters:
labels (np.ndarray) – The label array.
data_slice (Tuple[slice, ...]) – The slice of the label array on which to calculate the contour.
- Returns:
The calculated contour as a boolean mask array. Returns None if the contour parameter is less than 1, or if the label array has more than 2 dimensions.
- Return type:
Optional[np.ndarray]
- set_opacity(labels: list[int], value: float) None
Helper function to set the opacity of multiple labels to the same value. :param labels: list of labels to set the value for. :type labels: list[int] :param value: float alpha value to set. :type value: float
- refresh_colormap()
Refresh the label colormap after in-place opacity/color changes.
set_opacity mutates the colormap’s color_dict alphas in place. Rather than constructing a new DirectLabelColormap (which re-validates every color via transform_color - ~0.2s for a 37k-label graph), clear the colormap’s cached value->color mapping and re-assign the same object so napari rebuilds only the GPU texture (~0.08s).
Setting colormap also emits selected_label, which triggers _ensure_valid_label and would rebuild the colormap a second time; that validation is only needed when the painting label changes, not on a highlight/opacity refresh, so block it here.
- data_setitem(indices, value, refresh=True)
Override to handle read-only data (e.g. GraphArrayView).
When the underlying data does not support __setitem__ (read-only), accumulate paint atoms during a drag (respecting napari’s block_history mechanism) and only fire events.paint once when the drag completes. For writable arrays (numpy), fall back to the default implementation.
- _paint_region_with_mask(slice_key, mask, new_label, dims_to_paint, refresh=True, region_data=None)
Override to handle read-only data (e.g. GraphArrayView).
napari ≥0.8 equivalent of
data_setitemabove. This method writes the painted bounding box straight back withself.data[slice_key] = region_data. Read-only data cannot take that write, so run the same steps napari does, minus the write-back: the region is materialized as a numpy copy, so painting into it records the undo atom (firing events.paint, which is what upstream code acts on) and updates the display, while the underlying array is left untouched.
- undo()
Override undo for read-only data (e.g. GraphArrayView).
napari’s default Labels.undo() calls data_setitem() to restore old values. For read-only data, ContourLabels.data_setitem() cannot write to the underlying array and instead fires events.paint as a signal for upstream code to handle the change. Firing events.paint during an undo triggers the same paint-event callbacks that initiated the undo in the first place, causing a recursive loop and a TypeError.
This override breaks the loop by dropping the display buffer and re-slicing, without going through data_setitem or emitting any paint event. Only the display buffer was ever updated, the underlying array still holds the pre-stroke segmentation.
This method is called (via super().undo()) from TrackLabels in three situations: reverting a failed paint on the main layer, reverting a failed paint on an ortho-view copy of the layer, and rolling back an invalid action inside _on_paint error handling.
The undone item is dropped rather than handed to the redo queue: a paint that never reached the data cannot be re-applied by this layer, and what the user redoes is the funtracks action. Leaving the redo queue empty is also what
keeps napari’s own Labels.redo(), bound to Ctrl+Shift+Z, harmless here.
- _abort_stroke()
Override for read-only data (e.g. GraphArrayView).
napari >= 0.8 stages the atoms of an encircle-and-fill stroke (right click in paint mode) instead of committing them one by one, and aborts the stroke when the tool is disabled mid-stroke, e.g. by a mode switch. Its abort walks the staged atoms backwards and writes each one back into the array, either directly or via
_replay_masked_atom, which read-only data cannot take.Nothing was ever written (see
_paint_region_with_mask), so dropping the staged atoms and re-slicing is all the revert this layer needs, and, as inundo, it avoids emitting a paint event that would re-enter _on_paint.
- redo()
Override redo for read-only data (e.g. GraphArrayView). There is nothing to do here in our use case, since we have our own history logic, but because napari binds Ctrl+Shift+Z to Labels.redo() we should override here in case the user tries to redo on an ortho-view, triggering the TypeError: ‘LazyArrayWrapper’ object does not support item assignment error.