{"name":"quai-workbench-napari","display_name":"quai","visibility":"public","icon":null,"categories":[],"schema_version":"0.3.0","on_activate":null,"on_deactivate":null,"contributions":{"commands":[{"id":"quai-workbench-napari.quai_wb_widget","title":"Annotation workbench","python_name":"quai_workbench_napari.wb_widget:QuaiWBWidget","short_title":null,"category":null,"icon":null,"enablement":null}],"readers":null,"writers":null,"widgets":[{"command":"quai-workbench-napari.quai_wb_widget","display_name":"Annotation workbench","autogenerate":false,"default_dock_area":"right","tabify":false}],"sample_data":null,"themes":null,"menus":{},"submenus":null,"keybindings":null,"configurations":{}},"package_metadata":{"metadata_version":"2.4","name":"quai-workbench-napari","version":"0.2.0","dynamic":["license-file"],"platform":null,"supported_platform":null,"summary":"napari plug-in to create ground-truth data for quai.","description":"# quai annotation workbench\n\n[napari](https://napari.org/) plug-in to create ground-truth data for `quai`.\n\nAnnotations are kept in an **annotation project**: a folder that records every\nsample, every saved version of its labels, and the source image each sample came\nfrom, so annotation work is traceable and can be resumed at any time.\n\n**Supported:** single-channel 2D images and 3D (ZYX) volumes in TIFF files, with\nsemantic labels (each pixel value is a class); random regions of the project's crop\nsize, from all source images or from images selected by `quai select-samples`;\npredictions from quai to correct; exports that `quai storage import-annotations`\nversions for training. **Planned later:** choosing regions on an overview of the\nwhole image (with OME-Zarr support), instance labels, and multichannel images.\n\nFor a standalone walkthrough with practice images and optional quai integration, see [**Tutorial 14: quai annotation workbench**](https://www.aitoo.ch/quai/tutorials/0.4.0/tutorial-14-annotation-workbench.pdf). The complete quai tutorials are available to quai users [on request](https://aitoo.ch/#contact).\n\n# Install\n\nInstall [uv](https://docs.astral.sh/uv/getting-started/installation/) once.\n\n### Install quai-workbench-napari\n\nCreate an environment (Python 3.12 or newer) and install the plug-in with its dependencies. Annotating does not need `quai` or a quai license. Working with quai's outputs (selections, predictions, `quai storage import-annotations`, and 3D in particular) needs quai 0.4.0 or newer.\n\nThe example uses Python 3.12; uv downloads it if needed.\n\n```bash\nuv venv --python 3.12 .venv\nsource .venv/bin/activate        # Windows (PowerShell): .venv\\Scripts\\Activate.ps1\nuv pip install \"napari[all]\" quai-workbench-napari\n```\n\n**If you also use quai-atlas**, install both into one environment with Atlas's `napari` extra instead, which brings napari and the workbench:\n\n```bash\nuv pip install \"quai-atlas[napari]>=0.2.0\"\n```\n\nAtlas then opens images and starts the workbench with its own Python, with nothing to configure. Don't add `napari[all]` to that environment: it would install a second Qt binding (PyQt) next to Atlas's PySide6. See Atlas's README or [Tutorial 15](https://www.aitoo.ch/quai/tutorials/0.4.0/tutorial-15-browsing-experiments-with-quai-atlas.pdf), section 9.\n\n# Annotating\n\nStart **napari** and open **Plugins → Annotation workbench (quai)**.\n\n```sh\n$ napari\n```\n\n### Create or open a project\n\n* **New project** asks for:\n  * a **project folder** (new or empty), where the project will be stored;\n  * the **source images folder** (2D TIFF images, or ZYX stacks for a 3D project; subfolders are included). Source images are only read, never modified;\n  * a **project name**;\n  * the **classes**, comma-separated in label order, **background first** (label 0). For example `background, nucleus, border` gives labels 0, 1, and 2;\n  * the **crop size** of the regions to annotate (default 512×512). Smaller regions are quicker to annotate, but more context may help the neural network learn;\n  * the **maximum overlap** allowed between regions taken from the same image (default 20 %).\n* **Open project** opens an existing project folder. If the source images have moved, you are asked to locate them.\n* A project can be edited by one napari session at a time. If it is open elsewhere, you are told where; take over only if that session has ended, otherwise its unsaved work may be lost.\n\nEnter your name under **Annotator** to have it recorded with each saved version. The name is remembered for you on this computer (it is not stored in the project, which colleagues may share). Under the field, the panel shows who saved last and when, so you can tell whether the name is right before continuing someone else's work. Saving without a name works, but the status line points it out. \"Completed regions\" and \"Saved drafts\" count the current saved state of each region once, across the whole project. Unsaved edits do not change these counts until saved. Hover for contributors, historical revision counts, and dates. To list them without opening napari:\n\n```sh\n$ quai-wb-annotators /path/to/project          # or --json\n```\n\n### Annotate\n\n* **Next random crop** picks a random region of the chosen size from a random source image, respecting the maximum overlap with regions already saved. The image and an empty **Annotation** layer are added to napari.\n* Paint the labels in the **Annotation** layer. The legend in the panel shows which label value is which class.\n* **Save draft** stores the labels as a **draft**. You can save as often as you like; each save is kept as a new version.\n* **Complete** offers **Complete**, **Save draft**, **Discard changes**, and **Cancel** when labels differ from when the region was opened. Choosing Complete saves and marks the region as **fully annotated**. Only completed regions are used for training. If a region contains nothing of interest (only background), still complete it: the network also needs to see such areas.\n* **Revert** discards edits made since the last save.\n* Editing a completed region turns it back into a draft until you complete it again.\n* The **sample list** shows every saved region and its state (draft or complete). Click a region to reopen it.\n* Before you move to another region, open another project, or close napari or the panel with unsaved edits, you are asked whether to **Complete**, **Save draft**, **Discard changes**, or **Cancel**.\n\nLabels with values that are not classes of the project are refused with a message; nothing is saved.\n\n### 3D (volumetric) projects\n\nChoose **3D (ZYX)** under **Images** in **New project** to annotate single-channel ZYX stacks (TIFF; channel and time axes are not supported).\n\n* Regions are **subvolumes**. Set their size per axis (default 16 × 96 × 96 voxels); it should cover the training patch of your quai campaign. A stack without axis metadata is read as ZYX.\n* The voxel **spacing** is read from OME-TIFF or ImageJ metadata when it is complete for all three axes (in nm, µm, or mm). Otherwise you are asked for it the first time you save a region of that stack; known values are filled in. You can also set a project default for stacks without metadata, at creation or in the spacing dialog. While the project has no default, the first prompt offers the entered spacing as the default (untick it if your stacks differ), so stacks without metadata, including selected stacks already in the queue, are not asked one by one. **Spacing** shows or changes the current stack's spacing; changed values are recorded as user-supplied. Use it only to correct a missing or wrong calibration: it changes the recorded spacing and the display scale, not the pixels. When stacks have different spacings, a note lists them: when a save or import first makes them differ, when the project is opened, and before an export that contains them. quai's default 3D campaign transforms work with one spacing per dataset; to train on several spacings, specialize them, otherwise annotate stacks of each spacing in a separate project. The Spacing dialog's checkbox shows whether the current spacing is also the project default.\n* The subvolume opens at its middle slice, scaled by its spacing. Paint slice by slice in napari's 2D view, moving through Z with the slider. napari's 3D view shows the whole subvolume; there, napari only edits voxels that already have a label (repainting and erasing work, painting on background does nothing). **Save draft**, **Complete**, **Revert**, and **Discard changes** work on the whole subvolume. There is no per-slice completion: Complete means every slice of the subvolume is annotated.\n* **Training in quai:** the export records each sample's spacing, but quai's 3D campaign transforms do not read it. Set the run's `voxel_size` to the recorded spacing and choose a `patch_size` (in the resampled space) that fits the subvolumes; see quai's annotation import guide. `quai storage import-annotations` reports a note when an export has several spacings.\n* Selected stacks and their predictions work as for 2D images (see \"Annotating images selected by quai\"): **Next region from the selection** draws a random subvolume of the next selected stack, prefilled with the matching part of its prediction. Whole stacks are never opened.\n* If cells span many slices, most of them touch the top or bottom of a thin subvolume; a deeper subvolume (more Z slices) leaves more cells whole.\n\n# Two kinds of project\n\nA project is made for one purpose, fixed when it is created, and shows only the buttons for it:\n\n* **Manual project** (**New project**): annotate the images of a folder from scratch. **Next random crop** draws regions of any image in the sources folder. Nothing is imported from quai.\n* **Selection project** (**New project from quai selection**): correct the predictions of the images one `quai select-samples` run chose. **Next region from the selection** draws regions of the selected images in rank order. Make one selection project per round of the active-learning loop.\n\nBoth export completed regions for quai the same way. Projects made by earlier versions of the workbench, before projects were manual or selection projects, can't be opened: export their completed annotations with the version that made them, then create a new project.\n\n# Annotating images selected by quai\n\n`quai select-samples` picks the images a model is most uncertain about. To annotate them:\n\n* Choose **New project from quai selection** and the folder `quai select-samples` wrote (with `selection_manifest.json` and `selected_images.csv`). That is the only folder you choose, also when the experiment and data folders were copied, moved, or opened from another computer or share.\n* The plug-in finds the selected images, the model's classes and the uncertainty analysis from quai's records, and checks each image's content against what quai recorded; an image with other content is refused. If a recorded folder can't be found (for example a data repository on another share), you are asked once where it is on this computer; the answer is remembered (**Remembered folders** lists and forgets them).\n* It proposes the project: the folder the uncertainty analysis read (the pool) as the source images folder, the model's classes in its order, and a name. It says whether predictions of the images were found. You choose where to keep the project; nothing is created if none of the images can be queued. A project that was open stays as it is.\n* The selected images join the **selection queue** in rank order, with their rank, score and the selection's provenance; nothing is opened or copied yet.\n* The runs in the experiment that predicted the selected images are offered, with the model each was made with (the selection's own model first; runs with identical predictions of these images are offered once). Choose one, or decline: regions then open with empty labels.\n* **Find predictions** looks again, for example after you ran `quai full-inference` on the selected images. A project's predictions come from one model: a run of that model fills only images without a prediction; a run of another model replaces them only if you confirm, and only if it predicts every image that has one. Saved regions never change. If the project's selection folder has moved, you are asked for it, and it is checked against the one recorded in the project.\n* **Next region from the selection** draws a **random region** of the next image in the queue, of the project's crop size (the whole extent along axes where the image is smaller), with the overlap limit, prefilled with the matching part of its prediction. Annotate, **Save draft**, and **Complete** as usual. Each region records the image's selection rank, score, and metric; both are carried into exports.\n* The queue takes the images in turn and wraps around, so each image gives one region per pass; it continues where it left off after a restart. An image with no room for another region under the overlap limit is passed over and named in the status line. **Selection queue** lists the images with their status and number of regions; **Done with this image** and **Skip** take an image out, **Put back in queue** returns it.\n* Regions are random on purpose: choosing them by hand favours easy regions. Showing the whole image to choose a region is planned with OME-Zarr support.\n\n### Correcting predictions\n\n* A prediction is attached to the image of the same name only if it has the image's shape and its labels are the project's classes, in the same order. When the prediction run keeps an output list (quai 0.4.0), the prediction must be in it, unchanged, and the image must be the one it was made from (the same content); otherwise it is refused.\n* For an ensemble, the fused prediction (`ensemble_<name>.tif`) is used, not the individual models'. Predictions never become ground truth on their own, and never replace a region you have saved.\n* A region's prediction is stored with the region when you first save it, so the prediction folder is not needed afterwards. If the prediction file was moved or changed before then, you can continue without it or locate the folder it was moved to.\n* Edit the labels and **Complete**. For labels changed since opening, the dialog offers **Complete**, **Save draft**, **Discard changes**, and **Cancel**. Complete keeps the labels and records an unchanged prediction as **accepted**, or changed labels as **corrected**, automatically. Discard changes restores the labels from when you opened the region without saving or completing it; earlier explicit saves remain in history, so the restored labels may be unsaved relative to the latest save. Cancel keeps editing without writing anything. **Revert** continues to restore the last saved labels. Existing `rejected` decisions remain readable and exportable; the dialog no longer creates them.\n* Correcting a prediction run's output without a selection is not offered in new projects. To correct the predictions of a whole pool, run `quai select-samples` with `--k` at least the number of images.\n\nDo not edit these files by hand. The format is specified in `annotation-record-schema-v1.md`.\n\n# Reviewing saved drafts\n\nThe sample list offers **All**, **Drafts**, and **Complete** filters with counts.\n**Next draft** cycles through saved unfinished regions. **Next region from the\nselection** draws regions of the selected images.\n\nWhen leaving an edited region or completing it, use the same choices:\n**Complete** saves and makes it eligible for export; **Save draft** saves unfinished\nwork; **Discard changes** restores opening labels without writing; **Cancel** keeps\nediting. Cancelling panel closure reopens the panel. Explicit earlier saves remain\nin history. **Revert** still restores the most recently saved labels.\n\n**Complete all drafts** previews the affected samples and requires confirmation\nthat all are fully annotated, including imported predictions. Every draft passes\nfull pixel validation before one project-record replacement completes the batch;\nif validation fails, none is completed.\n\n**Discard all drafts** previews how many samples will return to a completed\nannotation and how many will become unannotated. Confirmation appends discard\nevents in one project-record replacement, preserving all revisions and blobs.\nNever-completed samples reopen without labels and can receive predictions again.\nNew edits can be saved afterward, retaining the historical revision chain.\nThese discard events are an optional project-record extension; use the updated\nplugin to reopen projects containing them. The export format is unchanged.\n\n# Scope of the controls\n\n- **Current region:** Save draft, Complete, Revert; Revert restores the last save.\n- **Sample navigation:** Next random crop (manual projects), Next region from the\n  selection (selection projects), Next draft.\n- **Saved drafts (whole project):** Complete all drafts and Discard all drafts.\n- **quai selection** (selection projects): Find predictions, Selection queue, and\n  Remembered folders. Predictions open with the regions drawn from predicted\n  images and never replace manual annotations.\n- **Export (completed annotations):** Export for quai.\n\nControls are disabled when there is no eligible region, queue, draft, or completed\nannotation. Edit controls update as labels change; all controls stay disabled\nwhile a worker runs. Every region of a project shares its class mapping and the\noverlap limit. Each sample retains its own geometry; prediction files must match\nthe source shape before a region is cut from them.\n","description_content_type":"text/markdown","keywords":null,"home_page":null,"download_url":null,"author":"Aaron Ponti","author_email":"aaron@aaronponti.ch","maintainer":null,"maintainer_email":null,"license":"Apache-2.0","classifier":["Framework :: napari"],"requires_dist":["napari<0.11,>=0.9.2","numpy>=1.25","pydantic!=2.11.*,<3,>=2.8","qtpy>=2.4","tifffile>=2022.7.28","pytest; extra == \"test\"","pytest-qt; extra == \"test\""],"requires_python":">=3.12","requires_external":null,"project_url":["Homepage, https://www.aitoo.ch/#quai","Documentation, https://www.aitoo.ch/quai/tutorials/0.4.0/tutorial-14-annotation-workbench.pdf"],"provides_extra":["test"],"provides_dist":null,"obsoletes_dist":null},"npe1_shim":false}