Intersection Over Union (IoU)

Module Interface

class torchmetrics.detection.iou.IntersectionOverUnion(box_format='xyxy', iou_threshold=None, class_metrics=False, respect_labels=True, **kwargs)[source]

Computes Intersection Over Union (IoU).

As input to forward and update the metric accepts the following input:

  • preds (List): A list consisting of dictionaries each containing the key-values (each dictionary corresponds to a single image). Parameters that should be provided per dict:

    • boxes (Tensor): float tensor of shape (num_boxes, 4) containing num_boxes detection boxes of the format specified in the constructor. By default, this method expects (xmin, ymin, xmax, ymax) in absolute image coordinates.

    • labels: IntTensor of shape (num_boxes) containing 0-indexed detection classes for the boxes.

  • target (List): A list consisting of dictionaries each containing the key-values (each dictionary corresponds to a single image). Parameters that should be provided per dict:

    • boxes (Tensor): float tensor of shape (num_boxes, 4) containing num_boxes ground truth boxes of the format specified in the constructor. By default, this method expects (xmin, ymin, xmax, ymax) in absolute image coordinates.

    • labels (Tensor): integer tensor of shape (num_boxes) containing 0-indexed ground truth classes for the boxes.

As output of forward and compute the metric returns the following output:

  • iou_dict: A dictionary containing the following key-values:

    • iou: (Tensor)

    • iou/cl_{cl}: (Tensor), if argument class metrics=True

Parameters:
  • box_format (str) – Input format of given boxes. Supported formats are [`xyxy`, `xywh`, `cxcywh`].

  • iou_thresholds – Optional IoU thresholds for evaluation. If set to None the threshold is ignored.

  • class_metrics (bool) – Option to enable per-class metrics for IoU. Has a performance impact.

  • respect_labels (bool) –

    Ignore values from boxes that do not have the same label as the ground truth box. Else will compute Iou

    between all pairs of boxes.

  • kwargs (Any) – Additional keyword arguments, see Advanced metric settings for more info.

Example:

>>> import torch
>>> from torchmetrics.detection import IntersectionOverUnion
>>> preds = [
...    {
...        "boxes": torch.tensor([
...             [296.55, 93.96, 314.97, 152.79],
...             [298.55, 98.96, 314.97, 151.79]]),
...        "labels": torch.tensor([4, 5]),
...    }
... ]
>>> target = [
...    {
...        "boxes": torch.tensor([[300.00, 100.00, 315.00, 150.00]]),
...        "labels": torch.tensor([5]),
...    }
... ]
>>> metric = IntersectionOverUnion()
>>> metric(preds, target)
{'iou': tensor(0.8614)}

Example:

The metric can also return the score per class:

>>> import torch
>>> from torchmetrics.detection import IntersectionOverUnion
>>> preds = [
...    {
...        "boxes": torch.tensor([
...             [296.55, 93.96, 314.97, 152.79],
...             [298.55, 98.96, 314.97, 151.79]]),
...        "labels": torch.tensor([4, 5]),
...    }
... ]
>>> target = [
...    {
...        "boxes": torch.tensor([
...               [300.00, 100.00, 315.00, 150.00],
...               [300.00, 100.00, 315.00, 150.00]
...        ]),
...        "labels": torch.tensor([4, 5]),
...    }
... ]
>>> metric = IntersectionOverUnion(class_metrics=True)
>>> metric(preds, target)
{'iou': tensor(0.7756), 'iou/cl_4': tensor(0.6898), 'iou/cl_5': tensor(0.8614)}
Raises:

ModuleNotFoundError – If torchvision is not installed with version 0.8.0 or newer.

plot(val=None, ax=None)[source]

Plot a single or multiple values from the metric.

Parameters:
  • val (Union[Tensor, Sequence[Tensor], None]) – Either a single result from calling metric.forward or metric.compute or a list of these results. If no value is provided, will automatically call metric.compute and plot that result.

  • ax (Optional[Axes]) – An matplotlib axis object. If provided will add plot to that axis

Return type:

Tuple[Figure, Union[Axes, ndarray]]

Returns:

Figure object and Axes object

Raises:

ModuleNotFoundError – If matplotlib is not installed

>>> import torch
>>> from torchmetrics.detection import IntersectionOverUnion
>>> preds = [
...    {
...        "boxes": torch.tensor([[296.55, 93.96, 314.97, 152.79], [298.55, 98.96, 314.97, 151.79]]),
...        "scores": torch.tensor([0.236, 0.56]),
...        "labels": torch.tensor([4, 5]),
...    }
... ]
>>> target = [
...    {
...        "boxes": torch.tensor([[300.00, 100.00, 315.00, 150.00]]),
...        "labels": torch.tensor([5]),
...    }
... ]
>>> metric = IntersectionOverUnion()
>>> metric.update(preds, target)
>>> fig_, ax_ = metric.plot()
../_images/intersection_over_union-1.png
>>> # Example plotting multiple values
>>> import torch
>>> from torchmetrics.detection import IntersectionOverUnion
>>> preds = [
...    {
...        "boxes": torch.tensor([[296.55, 93.96, 314.97, 152.79], [298.55, 98.96, 314.97, 151.79]]),
...        "scores": torch.tensor([0.236, 0.56]),
...        "labels": torch.tensor([4, 5]),
...    }
... ]
>>> target = lambda : [
...    {
...        "boxes": torch.tensor([[300.00, 100.00, 315.00, 150.00]]) + torch.randint(-10, 10, (1, 4)),
...        "labels": torch.tensor([5]),
...    }
... ]
>>> metric = IntersectionOverUnion()
>>> vals = []
>>> for _ in range(20):
...     vals.append(metric(preds, target()))
>>> fig_, ax_ = metric.plot(vals)
../_images/intersection_over_union-2.png

Functional Interface

torchmetrics.functional.detection.iou.intersection_over_union(preds, target, iou_threshold=None, replacement_val=0, aggregate=True)[source]

Compute Intersection over Union between two sets of boxes.

Both sets of boxes are expected to be in (x1, y1, x2, y2) format with 0 <= x1 < x2 and 0 <= y1 < y2.

Parameters:
  • preds (Tensor) – The input tensor containing the predicted bounding boxes.

  • target (Tensor) – The tensor containing the ground truth.

  • iou_threshold (Optional[float]) – Optional IoU thresholds for evaluation. If set to None the threshold is ignored.

  • replacement_val (float) – Value to replace values under the threshold with.

  • aggregate (bool) – Return the average value instead of the full matrix of values

Return type:

Tensor

Example::

By default iou is aggregated across all box pairs e.g. mean along the diagonal of the IoU matrix:

>>> import torch
>>> from torchmetrics.functional.detection import intersection_over_union
>>> preds = torch.tensor(
...     [
...         [296.55, 93.96, 314.97, 152.79],
...         [328.94, 97.05, 342.49, 122.98],
...         [356.62, 95.47, 372.33, 147.55],
...     ]
... )
>>> target = torch.tensor(
...     [
...         [300.00, 100.00, 315.00, 150.00],
...         [330.00, 100.00, 350.00, 125.00],
...         [350.00, 100.00, 375.00, 150.00],
...     ]
... )
>>> intersection_over_union(preds, target)
tensor(0.5879)
Example::

By setting aggregate=False the full IoU matrix is returned:

>>> import torch
>>> from torchmetrics.functional.detection import intersection_over_union
>>> preds = torch.tensor(
...     [
...         [296.55, 93.96, 314.97, 152.79],
...         [328.94, 97.05, 342.49, 122.98],
...         [356.62, 95.47, 372.33, 147.55],
...     ]
... )
>>> target = torch.tensor(
...     [
...         [300.00, 100.00, 315.00, 150.00],
...         [330.00, 100.00, 350.00, 125.00],
...         [350.00, 100.00, 375.00, 150.00],
...     ]
... )
>>> intersection_over_union(preds, target, aggregate=False)
tensor([[0.6898, 0.0000, 0.0000],
        [0.0000, 0.5086, 0.0000],
        [0.0000, 0.0000, 0.5654]])