# annotation

Python API: `luxonis_train.utils.annotation`

Turns the predictions of a model into dataset annotations.

## Functions

### default_annotate

```python
def default_annotate(head: lxt.nodes.BaseHead, head_output: Packet[Tensor], image_paths: list[Path], config_preprocessing: PreprocessingConfig) -> DatasetIterator:
```

Convert the head outputs of one batch into dataset records.

[BaseHead.annotate](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/heads/base_head.md)
returns this generator. It supports the labels `"boundingbox"`, `"keypoints"`, `"instance_segmentation"`, `"segmentation"`,
`"classification"`, and `"text"`. It reads the entry of each label that `head.task` requires.

For each image, the generator reads the image file to get the original size.
[transform_boxes](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/utils/spatial_transforms.md),
[transform_keypoints](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/utils/spatial_transforms.md),
and
[transform_masks](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/utils/spatial_transforms.md)
map the predictions to the original image. Each record has the keys `"file"`, `"task_name"`, and `"annotation"`. The
`"annotation"` entry depends on the label:

 * `"boundingbox"`: one record for each box, with `"instance_id"`, the class name, and the normalized `x`, `y`, `w`, and `h`.
   Columns `0` to `3` of the prediction hold the `xyxy` box, and column `5` holds the class index.
 * `"keypoints"`: one record for each instance, with `"instance_id"` and `(x, y, visibility)` tuples. The visibility is the third
   value of the prediction, rounded.
 * `"instance_segmentation"`: one record for each instance, with `"instance_id"` and a mask of the original size. The mask is
   `True` where the resized prediction is not zero.
 * `"segmentation"`: one record for each class, with the class name and a mask from
   [seg_output_to_bool](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/utils/segmentation.md).
 * `"classification"`: one record with the class of the highest score.
 * `"text"`: one record with a `"metadata"` entry. Its `"text"` key holds the text that `head.decoder` reads from the `"ocr"`
   entry.

When each required label other than `"text"` has no predictions for an image, the generator yields one record with only the
`"file"` key. A task that requires only `"text"` never gives such a record. The generator raises its errors during the iteration,
not at the call.

Warning: Without `keep_aspect_ratio`, the generator does not scale the box and keypoint coordinates from `train_image_size`. The
coordinates are wrong when the original size differs from it.

Parameters

 * `head` (`lxt.nodes.BaseHead`): The head that made the predictions. The generator reads its `task`, `task_name`, `classes`, and
   `name`. For the `"text"` label, it also reads `decoder`.
 * `head_output` (`Packet[Tensor]`): The output packet of the head. The entry of each label holds one element for each image. The
   `"text"` label reads the `"ocr"` entry.
 * `image_paths` (`list[Path]`): The paths of the original images, in the order of the batch.
 * `config_preprocessing` (`PreprocessingConfig`): The preprocessing config. The generator reads `train_image_size` and
   `keep_aspect_ratio`.

Returns

 * `DatasetIterator`

Yields

 * One record in the `luxonis_ml` record format.

Raises

 * `ValueError`: When `head.task` requires a label that the generator does not support, or when a head without `decoder` requires
   the `"text"` label.
 * `FileNotFoundError`: When OpenCV cannot read an image.

## Attributes

### ALLOWED_ANNOTATE_LABELS
