# detection_confusion_matrix

Python API: `luxonis_train.attached_modules.metrics.confusion_matrix.detection_confusion_matrix`

The confusion matrix for bounding boxes, which matches predictions to labels by IoU.

## Classes

### DetectionConfusionMatrix

Confusion matrix for bounding box predictions.

 * `Inputs:`: * `boundingbox` (`list[Tensor]`): [Mi, 6] per image, `[x1, y1, x2, y2, conf, class]`, pixels
    * `target_boundingbox` (`Tensor`): [N, 6], `[batch, class, x, y, w, h]`, `xywh` normalized
 * `Outputs:`: * `mcc` (`Tensor`): scalar MCC of the whole matrix, see
   [compute_mcc](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/metrics/confusion_matrix/utils.md)
    * `confusion_matrix` (`Tensor`): [nclasses + 1, nclasses + 1] counts, rows are targets, last row and column are background
 * `Formula:`: The metric matches the boxes of each image. With the IoU threshold t from `iou_threshold`, a target box and a
   prediction match when IoU > t. The class of the prediction does not affect the match. Each target box takes the first
   prediction in row order that it matches, not the one with the highest IoU. Several target boxes can take the same prediction.
   Then: * A target box with a match adds `1` to its class row in the column of the class of its prediction.
    * A target box without a match adds `1` to its class row in the background column.
    * A prediction that no target box takes adds `1` to the background row in its class column.
    * An image without target boxes and without predictions adds `1` to the cell `[n_classes, n_classes]`. In an image without
      target boxes, without predictions, or without a match, each class counts at most once. For example, three predictions of
      class `0` in an image without target boxes add `1`, not `3`, to the background row.

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

> **Notes**
> The metric ignores the confidence column, so each prediction of the node counts. [FomoConfusionMatrix](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/metrics/confusion_matrix/fomo_confusion_matrix.md) and [InstanceSegmentationConfusionMatrix](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/metrics/confusion_matrix/instance_segmentation_confusion_matrix.md) extend this class.

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

```yaml
- name: EfficientBBoxHead
  inputs: [RepPANNeck]
  metrics:
    - name: DetectionConfusionMatrix
```

 * `Compatible with:`: * 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)
       * [EfficientKeypointBBoxHead](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/heads/efficient_keypoint_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)
       * [PrecisionSegmentBBoxHead](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/heads/precision_seg_bbox_head.md)

#### Methods

##### init

```python
def __init__(iou_threshold: float = 0.45, **kwargs):
```

Initialize the metric and its `confusion_matrix` state.

The state is a zero `int64` tensor of shape `[n_classes + 1, n_classes + 1]`. A distributed run adds the states of all processes.
The number of classes comes from the node, so a metric without a node raises `RuntimeError`.

Parameters

 * `iou_threshold` (`float`): The value that the IoU of a target box and a prediction must exceed for a match.
 * `**kwargs`: Keyword arguments forwarded to
   [BaseMetric](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/metrics/base_metric.md),
   such as `node`.

##### compute

```python
def compute(self) -> dict[str, Tensor]:
```

Return the MCC and the matrix since the last reset.

> **Example**
> The batch has one image with one target box of class `0`. The first prediction covers it. The second prediction, of class `1`, matches no target box. A `SimpleNamespace` stands in for the node.

```pycon
>>> import torch
>>> from types import SimpleNamespace
>>> node = SimpleNamespace(
...     task=None,
...     n_classes=2,
...     original_in_shape=torch.Size([3, 10, 10]),
... )
>>> metric = DetectionConfusionMatrix(node=node)
>>> target = torch.tensor([[0, 0, 0.0, 0.0, 0.5, 0.5]])
>>> boxes = [
...     torch.tensor([[0, 0, 5, 5, 0.9, 0], [6, 6, 9, 9, 0.8, 1]])
... ]
>>> metric.update(boxes, target)
>>> metric.compute()["confusion_matrix"].tolist()
[[1, 0, 0], [0, 0, 0], [0, 1, 0]]
```

Returns

 * `dict[str, Tensor]`: A dictionary with two keys. * `"mcc"` holds the scalar MCC of the whole matrix, background included, see
   [compute_mcc](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/metrics/confusion_matrix/utils.md).
    * `"confusion_matrix"` holds the `int64` counts, of shape `[n_classes + 1, n_classes + 1]`. Rows are target classes, columns
      are predicted classes, and index `n_classes` is the background.

##### update

```python
def update(boundingbox: list[Tensor], target_boundingbox: Tensor):
```

Match the boxes of one batch and count the result.

The method converts the target boxes to `xyxy` pixels with the height and width of
[BaseAttachedModule.original_in_shape](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/base_attached_module.md).
It writes the converted boxes into `target_boundingbox`.
[BaseMetric.run_update](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/metrics/base_metric.md)
passes a clone, so the labels of the batch do not change. The method then matches the boxes of each image, as the class docstring
describes.

Parameters

 * `boundingbox` (`list[Tensor]`): The predicted boxes of each image, of shape `[M_i, 6]`, as `[x1, y1, x2, y2, conf, class]` in
   pixels. The length of the list is the batch size.
 * `target_boundingbox` (`Tensor`): The `boundingbox` label of the batch, of shape `[N, 6]`, as `[batch_index, class, x, y, w,
   h]`. The values are normalized, and `x` and `y` are the top-left corner.

#### Attributes

##### confusion_matrix

##### supported_tasks
