Annotation Export ================== WeightsLab can export bounding-box/segmentation annotations to a relabeling-tool format, so a dataset (or a slice of one) can be handed off for an outsourced relabeling pass. Three ways to trigger it, all backed by the same code path: - **Weights Studio UI** — an "Export" button next to Save/Grid settings, with a format picker (CVAT / Label Studio / V7). Triggers a browser download. - **CLI** — ``weightslab export`` connects over gRPC to a running experiment, same as ``weightslab cli``. - **Python** — :func:`wl.export_annotations`, called in-process (no gRPC round-trip needed since it already runs alongside the registered dataframe). Supported formats ------------------ .. list-table:: :header-rows: 1 :widths: 20 40 40 * - Format - Output shape - Schema reference * - ``cvat`` - A single CVAT XML 1.1 file (one ```` element per sample, with ````/```` children). - `CVAT XML format `_ * - ``label_studio`` - A single JSON file — a list of "tasks", each with a ``result`` list of ``rectanglelabels``/``polygonlabels`` entries. Coordinates are percentages (0-100) of the image's width/height, per Label Studio's convention. - `Label Studio export format `_ * - ``v7`` - A zip of one Darwin JSON 2.0 file per image (V7 matches annotations to images by filename on import). - `Darwin JSON reference `_ Bounding boxes are exported for every format. Segmentation masks are converted to polygons via OpenCV contour extraction — this needs the optional ``export`` extra: .. code-block:: bash pip install weightslab[export] Bounding-box-only export needs no extra dependency; if OpenCV isn't installed, segmentation samples still export their boxes and a warning is logged once, rather than failing the whole export. Usage ------ **Python** .. code-block:: python import weightslab as wl wl.export_annotations("cvat") # everything, under root_log_dir wl.export_annotations("label_studio", "val.json", origin="val_loader") wl.export_annotations("v7", "out/", class_names=["bg", "cat", "dog"]) wl.export_annotations("cvat", tags=["ToReview"]) # only samples tagged ToReview See :doc:`user_functions` for the full :func:`wl.export_annotations` reference. **CLI** .. code-block:: bash weightslab export --format cvat # everything, CVAT XML, into "." weightslab export -f v7 out/ --origin val_loader # V7/Darwin, val split only weightslab export -f cvat --tag ToReview # only samples tagged ToReview Connects over gRPC to a running experiment (``127.0.0.1:50051`` by default), same as ``weightslab cli``. See :doc:`user_commands` for every flag. **Weights Studio UI** The download-arrow icon button sits in the Details panel's header actions, between the manual-save and grid-settings buttons. Clicking it opens a small floating menu next to the button: - A **tag filter section** — one checkbox per existing ``tag:`` column (boolean or categorical), only shown if any tags exist. Leave every box unchecked to export the whole dataset; check one or more to restrict to samples carrying **any** of them. - Three **format buttons** — "Export to CVAT (XML)", "Export to Label Studio (JSON)", "Export to V7 / Darwin (zip)". Clicking a format button fires the ``ExportAnnotations`` gRPC call immediately (with the checked tags, or none) — there is no format preview step. A toast shows "Exporting annotations…", then either a success message with the image count and a browser download of the file, or an error message if the call fails. The UI always exports ground-truth targets; it does not currently expose the ``use_predictions``/``--predictions`` toggle that the Python and CLI paths have. .. note:: The export button is disabled in sandbox mode, with a tooltip explaining why — sandbox sessions can't download data out of the demo. **In-app chat agent** Because the chat agent (see :doc:`agent`) has general tool access to the live experiment process, you can also just ask for this in plain language -- e.g. "export the samples tagged ToReview to CVAT format for relabeling" -- and it calls :func:`wl.export_annotations` with the matching ``tags=`` argument itself. No special wiring is needed beyond the API existing. Filtering by tag ------------------ All three entry points accept a tag filter (``tags=`` in Python, ``--tag`` on the CLI, repeatable; the tag picker in the UI) that restricts the export to samples carrying **any** of the given tags -- boolean tags set via :func:`wl.tag_samples` or categorical values set via :func:`wl.set_categorical_tag` both work, since they share the same ``tag:`` column. Omit it to export every sample. This is the mechanism for a "send only what needs another look" relabeling handoff, e.g. tagging uncertain samples as ``ToReview`` during data exploration and exporting just that subset. How annotations are resolved ------------------------------ Every export path collects annotations from the same registered dataframe that backs the rest of WeightsLab (`get_dataframe()`), grouping the ``(sample_id, annotation_id)`` multi-index rows by sample: - **Boxes** — read from the ``target`` (or ``prediction``, with ``use_predictions=True``) column when it holds coordinate-shaped data (``(x1, y1, x2, y2[, conf][, cls])``), whether that's a single box per sample or several boxes exploded across annotation rows. - **Masks -> polygons** — read from the same column when it holds a dense ``(H, W)`` array (pixel value = class id); one polygon per connected region per class id. Two real gaps in the current data model drive the "best effort" behavior below — call these out explicitly if an export looks wrong: - **No dedicated class-id -> name registry.** Labels are resolved, in order: an explicit ``class_names`` argument; else a ``class_names`` attribute on the dataset object backing the relevant split; else ``"class_"``. - **No per-sample stored image path or dimensions.** A real image path is best-effort resolved from a few common dataset attribute names (``image_paths``, ``img_files``, ``images``, ``imgs``, ``files``, ``samples``); dimensions come from that file (via Pillow) or, for segmentation samples, directly from the mask's own shape. When no path resolves, the exported filename is synthetic (``sample_.jpg``) — **no image file is copied or embedded**, so you must ensure the filenames you upload to CVAT/Label Studio/V7 match the ones in the export.