---
title: Intersection Over Union (IoU)
description: Computes Intersection Over Union (IoU).
canonical: >-
  https://lightning.ai/docs/torchmetrics/stable/detection/intersection_over_union
---
# Intersection Over Union (IoU) {#intersection-over-union-iou}

## Module Interface {#module-interface}

### `class torchmetrics.detection.iou.IntersectionOverUnion(box_format='xyxy', iou_threshold=None, class_metrics=False, respect_labels=True, **kwargs)` {#torchmetrics.detection.iou.IntersectionOverUnion}

[\[source\]](https://github.com/Lightning-AI/torchmetrics/blob/v1.9.0/src/torchmetrics/detection/iou.py#L33-L312)

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`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)")): 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`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)")): 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`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)")): 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`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)"))
        
    *   iou/cl\_{cl}: ([`Tensor`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)")), if argument `class metrics=True`
        

Parameters:

*   **box\_format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")) – 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`](https://docs.python.org/3/builtins/functions.html#bool "(in Python v3.15)")) – Option to enable per-class metrics for IoU. Has a performance impact.
    
*   **respect\_labels** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool "(in Python v3.15)")) –
    
    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`](https://docs.python.org/3/library/typing.html#typing.Any "(in Python v3.15)")) – Additional keyword arguments, see [Advanced metric settings](/docs/torchmetrics/1.9.0/user-guide/overview.md#metric-kwargs) for more info.
    

Example:

```python
>>> 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:

```python
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**](https://docs.python.org/3/builtins/exceptions.html#ModuleNotFoundError "(in Python v3.15)") – If torchvision is not installed with version 0.8.0 or newer.

#### `plot(val=None, ax=None)` {#torchmetrics.detection.iou.IntersectionOverUnion.plot}

[\[source\]](https://github.com/Lightning-AI/torchmetrics/blob/v1.9.0/src/torchmetrics/detection/iou.py#L247-L312)

Plot a single or multiple values from the metric.

Parameters:

*   **val** (`Union`\[[`Tensor`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)"), [`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence "(in Python v3.15)")\[[`Tensor`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)")\], [`None`](https://docs.python.org/3/builtins/constants.html#None "(in Python v3.15)")\]) – 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`](https://docs.python.org/3/library/typing.html#typing.Optional "(in Python v3.15)")\[[`Axes`](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html#matplotlib.axes.Axes "(in Matplotlib v3.11.2)")\]) – An matplotlib axis object. If provided will add plot to that axis
    

Return type:

[`tuple`](https://docs.python.org/3/builtins/stdtypes.html#tuple "(in Python v3.15)")\[[`Figure`](https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure "(in Matplotlib v3.11.2)"), `Union`\[[`Axes`](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html#matplotlib.axes.Axes "(in Matplotlib v3.11.2)"), [`ndarray`](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray "(in NumPy v2.5)")\]\]

Returns:

Figure object and Axes object

Raises:

[**ModuleNotFoundError**](https://docs.python.org/3/builtins/exceptions.html#ModuleNotFoundError "(in Python v3.15)") – If matplotlib is not installed

```python
>>> 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](/docs/torchmetrics/1.9.0/static/_images/intersection_over_union-1.png)](/docs/torchmetrics/1.9.0/static/_images/intersection_over_union-1.png)

```python
>>> # 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](/docs/torchmetrics/1.9.0/static/_images/intersection_over_union-2.png)](/docs/torchmetrics/1.9.0/static/_images/intersection_over_union-2.png)

## Functional Interface {#functional-interface}

### `torchmetrics.functional.detection.iou.intersection_over_union(preds, target, iou_threshold=None, replacement_val=0, aggregate=True)` {#torchmetrics.functional.detection.iou.intersection_over_union}

[\[source\]](https://github.com/Lightning-AI/torchmetrics/blob/v1.9.0/src/torchmetrics/functional/detection/iou.py#L52-L128)

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`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)")) – The input tensor containing the predicted bounding boxes.
    
*   **target** ([`Tensor`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)")) – The tensor containing the ground truth.
    
*   **iou\_threshold** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional "(in Python v3.15)")\[[`float`](https://docs.python.org/3/builtins/functions.html#float "(in Python v3.15)")\]) – Optional IoU thresholds for evaluation. If set to None the threshold is ignored.
    
*   **replacement\_val** ([`float`](https://docs.python.org/3/builtins/functions.html#float "(in Python v3.15)")) – Value to replace values under the threshold with.
    
*   **aggregate** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool "(in Python v3.15)")) – Return the average value instead of the full matrix of values
    

Return type:

[`Tensor`](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor "(in PyTorch v2.15)")

Example::

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

```python
>>> 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:

```python
>>> 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]])
```

---

**Navigation**

- Parent: [Detection](/docs/torchmetrics/1.9.0/detection.md)
