# bbox_visualizer

Python API: `luxonis_train.attached_modules.visualizers.bbox_visualizer`

Draws bounding boxes, class labels, and scores.

## Classes

### BBoxVisualizer

Visualize bounding box predictions and targets.

The left image shows the targets. The right image shows the predictions.

 * `Inputs:`: * `prediction_canvas`, `target_canvas` (`Tensor`): [B, 3, H, W]
    * `predictions` (`list[Tensor]`): [Mi, 6] per image, `[x1, y1, x2, y2, conf, class]`, pixels
    * `targets` (`Tensor | None`): [N, 6], `[batch, class, x, y, w, h]`, `xywh` normalized
 * `Outputs:`: * `Tensor | tuple[Tensor, Tensor]`: [B, 3, H, W], a pair when targets are given

> **References**
> * Source: This project.
 * License: Apache-2.0 (this project)

> **Notes**
> Draws boxes with `torchvision` and local label/color helpers. The visualizer stores the `fill`, `font`, and `font_size` options but does not use them.

> **Example**
> Attached to a `EfficientBBoxHead` in `model.nodes`:

```yaml
- name: EfficientBBoxHead
  inputs: [RepPANNeck]
  visualizers:
    - name: BBoxVisualizer
```

 * `Compatible with:`: * Used by:
   [DetectionModel](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/detection/v1/model.md)
    * Nodes: *
      [EfficientBBoxHead](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/heads/efficient_bbox_head.md)
       * [PrecisionBBoxHead](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/heads/precision_bbox_head.md)

#### Methods

##### init

```python
def __init__(labels: dict[int, str] | list[str] | None = None, draw_labels: bool = True, draw_scores: bool = False, colors: dict[str, Color] | list[Color] | None = None, fill: bool = False, width: int | None = None, font: str | None = None, font_size: int | None = None, **kwargs):
```

Initialize the visualizer and resolve the class names and colors.

Parameters

 * `labels` (`dict[int, str] | list[str] | None`): Class names to draw. A dictionary maps a class index to a name. A list maps by
   position. When `None` or empty, the names come from the `classes` of the node, so the visualizer then needs a `node`.
 * `draw_labels` (`bool`): Whether to draw the class name next to each box. Defaults to `True`.
 * `draw_scores` (`bool`): Whether to write the confidence of each predicted box, with two decimals, in its label. Applies to the
   predictions only. Without `draw_labels`, the label is the confidence alone. Defaults to `False`.
 * `colors` (`dict[str, Color] | list[Color] | None`): Box colors. A dictionary maps a class name to a color. A list maps by class
   index. When `None`, each class gets a distinct color from
   [get_color](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/visualizers/utils.md),
   seeded with its index.
 * `fill` (`bool`): The drawing methods do not read it. Defaults to `False`.
 * `width` (`int | None`): Line width of the boxes, in pixels. When `None` or `0`, the width is one percent of the smaller canvas
   side, rounded down, and at least `1`.
 * `font` (`str | None`): The drawing methods do not read it. Defaults to `None`.
 * `font_size` (`int | None`): The drawing methods do not read it. Defaults to `None`.
 * `**kwargs`: Keyword arguments forwarded to
   [BaseVisualizer](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/visualizers/base_visualizer.md),
   such as `scale` and `node`.

##### draw_predictions

```python
def draw_predictions(canvas: Tensor, predictions: list[Tensor], scale: float = 1.0) -> Tensor:
```

Draw the predicted boxes of a batch on copies of the canvas images.

Each box gets the color of its class.
[get_prediction_labels](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/visualizers/utils.md)
builds its label from the class name, when `draw_labels` is set, and from the confidence, when `draw_scores` is set.

When `torchvision` raises `ValueError` for an image, the method logs a warning and continues with the input canvas as the output.
It discards the images drawn before the failure, and draws the remaining images into `canvas` in place.

> **Example**
> ```pycon
>>> import torch
>>> visualizer = BBoxVisualizer(
...     labels=["cat"], colors=["red"], draw_labels=False
... )
>>> canvas = torch.zeros(1, 3, 8, 8, dtype=torch.uint8)
>>> boxes = [torch.tensor([[2.0, 2.0, 6.0, 6.0, 0.9, 0.0]])]
>>> viz = visualizer.draw_predictions(canvas, boxes)
>>> bool((viz[0, 0] == 255).any()), bool((viz[0, 1] == 255).any())
(True, False)
```

Parameters

 * `canvas` (`Tensor`): `uint8` images of shape `[B, 3, H, W]`.
 * `predictions` (`list[Tensor]`): One tensor per image, of shape `[M_i, 6]` with rows `[x1, y1, x2, y2, conf, class]`. The coordinates are pixels of the unscaled image.
 * `scale` (`float`): Multiplier for the box coordinates. Pass the factor that scaled the canvas. Defaults to `1.0`.

Returns

 * `Tensor`: The images with the boxes drawn, of the same shape as `canvas`. A new tensor, except after a failure, when it is `canvas` itself.

##### draw_targets

```python
def draw_targets(canvas: Tensor, targets: Tensor) -> Tensor:
```

Draw the target boxes of a batch on copies of the canvas images.

The boxes of image `i` are the rows of `targets` whose first column equals `i`. [draw_bounding_box_labels](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/visualizers/utils.md) converts them from normalized `xywh` to pixel `xyxy` with the canvas size. Each box gets the color of its class, and its class name when `draw_labels` is set.

> **Example**
> ```pycon
>>> import torch
>>> visualizer = BBoxVisualizer(
...     labels=["cat"], colors=["red"], draw_labels=False
... )
>>> canvas = torch.zeros(1, 3, 8, 8, dtype=torch.uint8)
>>> targets = torch.tensor([[0, 0, 0.25, 0.25, 0.5, 0.5]])
>>> viz = visualizer.draw_targets(canvas, targets)
>>> viz.shape
torch.Size([1, 3, 8, 8])
>>> bool((viz[0, 0] == 255).any()), bool((viz[0, 1] == 255).any())
(True, False)
```

Parameters

 * `canvas` (`Tensor`): `uint8` images of shape `[B, 3, H, W]`. The method does not modify it.
 * `targets` (`Tensor`): Boxes of shape `[N, 6]` with rows `[batch_index, class, x, y, w, h]`. The coordinates are `xywh`
   normalized to `[0, 1]`.

Returns

 * `Tensor`: A new tensor of the same shape as `canvas` with the boxes drawn.

##### forward

```python
def forward(prediction_canvas: Tensor, target_canvas: Tensor, predictions: list[Tensor], targets: Tensor | None) -> tuple[Tensor, Tensor] | Tensor:
```

Draw the predicted boxes, and the target boxes when given.

> **Example**
> ```pycon
>>> import torch
>>> visualizer = BBoxVisualizer(labels=["cat"], colors=["red"])
>>> canvas = torch.zeros(1, 3, 8, 8, dtype=torch.uint8)
>>> boxes = [torch.tensor([[2.0, 2.0, 6.0, 6.0, 0.9, 0.0]])]
>>> visualizer(canvas, canvas, boxes, None).shape
torch.Size([1, 3, 8, 8])
>>> targets = torch.tensor([[0, 0, 0.25, 0.25, 0.5, 0.5]])
>>> len(visualizer(canvas, canvas, boxes, targets))
2
```

Parameters

 * `prediction_canvas` (`Tensor`): `uint8` images of shape `[B, 3, H, W]` to draw the predictions on.
 * `target_canvas` (`Tensor`): `uint8` images of shape `[B, 3, H, W]` to draw the targets on.
 * `predictions` (`list[Tensor]`): One tensor per image, of shape `[M_i, 6]` with rows `[x1, y1, x2, y2, conf, class]` in pixels. [draw_predictions](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/visualizers/bbox_visualizer.md) scales them by the `scale` factor.
 * `targets` (`Tensor | None`): Boxes of shape `[N, 6]` with rows `[batch_index, class, x, y, w, h]`, `xywh` normalized to `[0, 1]`. `None` when the batch has no `boundingbox` labels.

Returns

 * `tuple[Tensor, Tensor] | Tensor`: The pair `(targets, predictions)` of drawn images when `targets` is not `None`; otherwise only the predictions image. Each image has the shape of its canvas.

#### Attributes

##### supported_tasks
