← All answersAccuracy & training

How does Intersection over Union (IoU) evaluate bounding box accuracy?

Short answer

IoU scores how well two boxes match by dividing the area where they overlap by the total area they cover together. It ranges from 0 (no overlap) to 1 (identical). A prediction is usually counted as correct if its IoU with the ground-truth box clears a threshold like 0.5. IoU is the building block for both NMS and mAP.

On this pageRunnable codeInteractive demo

IoU answers one question: how much do these two rectangles agree? The formula is just overlap divided by combined area. Drag the boxes below to feel how quickly the score falls off, a prediction that looks close by eye often lands nearer 0.4 than 0.9.

Drag either box to see IoU change
ground truthprediction
IoU
0.537
0threshold 0.501
intersection
18,648 px²
union
34,752 px²

✓ Counts as a true positive at IoU ≥ 0.50

The formula in code

def iou(a, b):
    """a, b are boxes as (x1, y1, x2, y2)."""
    ix1, iy1 = max(a[0], b[0]), max(a[1], b[1])
    ix2, iy2 = min(a[2], b[2]), min(a[3], b[3])
    inter = max(0, ix2 - ix1) * max(0, iy2 - iy1)
    area_a = (a[2] - a[0]) * (a[3] - a[1])
    area_b = (b[2] - b[0]) * (b[3] - b[1])
    union = area_a + area_b - inter
    return inter / union if union > 0 else 0.0

It shows up in three places: as the match criterion for mAP (is this detection a hit?), as the overlap test inside NMS, and as part of modern box-regression losses (GIoU, DIoU, CIoU) that train the network to maximize overlap directly instead of just minimizing corner error.

The choice of IoU threshold is a dial for strictness. mAP@0.5 is lenient; mAP@0.5:0.95 averages across thresholds up to 0.95 and rewards boxes that are tightly, not just roughly, correct.