cellmap_flow.finetune.session.fill
Labelling a whole box of an annotation volume at once.
The Finetune tab’s “Seed” and “All background” buttons label the box on
screen in one click: from the model’s own prediction, for the user to clean
up with the brush, or all background (1), for a region of false positives.
Either way only unannotated voxels (0) are filled. A stroke the user painted
is a decision about that voxel; a seed is a guess. “Split objects” relabels
the box’s foreground by connected component (relabel_objects), so a
background wall painted through a merged object gives it two ids again.
The objects a seed writes come from post.segment, the segmenter that
fits the model (seed_labels takes its labels). Split Objects is
6-connected by default (face neighbours, scipy’s default): a one-voxel wall
the brush paints cuts an object under it, where under 26-connectivity the
voxels across a diagonal wall would still touch.
The write goes to MinIO, as cc3d_relabel’s does, not to the volume on disk:
MinIO holds strokes the periodic sync has not pulled yet, which is what “only
fill 0s” must see, and it is what neuroglancer reads. The caller then pulls
the changed chunks to disk with sync.sync_volume, so disk and MinIO agree
and the periodic sync has nothing to revert.
Attributes
Functions
|
|
|
Labels for a box from a segmentation: an id per object inside, 1 outside. |
|
The box's foreground (labels 2 and up) relabelled by connected component. |
|
The volume's |
|
Write |
|
Write |
|
Put the box back to |
Module Contents
- cellmap_flow.finetune.session.fill.logger
- cellmap_flow.finetune.session.fill.box_voxels(volume, offset_nm, shape_nm, volume_shape)
(lo, hi): the annotation voxels whose centres lie in a box, clipped to the volume.offset_nmandshape_nmare the box’s lower corner and size in world nm, as a good region records them;volumeis the volume’s record, for its grid. None when no voxel of the volume is in the box.
- cellmap_flow.finetune.session.fill.seed_labels(objects, existing, count_up=False)
Labels for a box from a segmentation: an id per object inside, 1 outside.
objectsis apost.segmentsegmenter’s output over the box (0 background, objects 1..n),existingwhat the box holds now. Each object gets an id of its own (_fresh_ids;count_upfor an instance target), so neighbouring objects are told apart, and a merge the model made shows as one colour to split; but an object the user has already painted part of takes the id painted there most, or the unpainted rest of it would be taught as a different object from its painted part. A binary or distance target reads every id as foreground, so the ids cost it nothing.
- cellmap_flow.finetune.session.fill.relabel_objects(existing, count_up=False, connectivity=1, per_slice=False)
The box’s foreground (labels 2 and up) relabelled by connected component.
Each component takes the id most of its voxels hold, so a stroke that joins two objects merges them into the id of the bigger. An id left on several components, an object a background wall cut in two, stays on the largest and the others get fresh ids (
_fresh_ids). Background (1) and unpainted (0) voxels are left alone. Returns(labels, counts):countshasobjects,split(components given a fresh id) andmerged(components that held more than one id).A cut has to go through every slice the object spans: the brush paints one slice, and an object cut in one slice is still one object above and below it.
splitis 0 then, which the page says. Withper_sliceeach z slice’s pieces are components on their own, so a wall in one slice splits that slice, and every slice of an object gets its own id.connectivity: as forpost.segment.connected_components.
- cellmap_flow.finetune.session.fill.open_served_labels(state, volume_id)
The volume’s
annotation/s0as MinIO serves it, open for writing.The bucket key is
<volume_id>.zarr, as for the sync.
- cellmap_flow.finetune.session.fill.fill_unpainted(state, volume_id, lo, hi, labels_for, local_zarr_path=None, undo=None)
Write
labels_for(existing)into the box[lo, hi)where the volume holds 0.labels_forgets the box as MinIO holds it and returns labels of the same shape (0 for “leave as it is”). Returns(n_foreground, n_background): how many voxels were filled with each. Nothing is written when nothing would change.undo, a list, gets(lo, hi, before, after)appended when something was written (restore_box).
- cellmap_flow.finetune.session.fill.rewrite_foreground(state, volume_id, lo, hi, relabel, local_zarr_path=None, undo=None)
Write
relabel(existing)’s labels over the box’s foreground voxels.relabelgets the box as MinIO holds it and returns(labels, counts)(relabel_objects); only foreground voxels (2 and up) whose label changed are written, so a stroke painted meanwhile elsewhere in the box is kept. Returns(n_changed, counts).undo: as forfill_unpainted.
- cellmap_flow.finetune.session.fill.restore_box(state, volume_id, lo, hi, before, after)
Put the box back to
beforewhere it still holdsafter: an undo.Only voxels the action changed and nobody has touched since go back, so a stroke painted in the box after the action is kept. Returns how many voxels were restored.