Skip to content
AI360Xpert
Beta

Intersection over Union

Intersection over Union divides the overlap of two boxes by their combined area, giving one number between 0 and 1 for how well boxes agree.

Intersection over Union scores box agreement as overlap divided by combined area, with upgrades that still guide boxes that miss entirely.
Intersection over Union scores box agreement as overlap divided by combined area, with upgrades that still guide boxes that miss entirely.

Why Does This Exist?

Detectors output coordinates, but coordinate distance means nothing: is 5 pixels off good or terrible? It depends on box size. IoU normalizes agreement into one scale-free number used everywhere in detection: matching anchors to ground truth, labeling positives in RPN training, suppressing duplicates in NMS, and deciding true positives in evaluation. One metric, four jobs, which is why every detection page leans on it.

Think of It Like This

Two picnic blankets on the grass

Two groups spread blankets that partly overlap. Overlap alone says little: 2 square meters shared matters differently for handkerchiefs versus circus tents. Divide the shared area by the total grass covered by either blanket and you get agreement independent of blanket size.

That ratio is IoU. Identical blankets score 1, touching corners score 0, and half-overlap lands somewhere sensible in between.

How It Actually Works

Definition and a worked example

IoU=Area(A∩B)/Area(A∪B)\text{IoU} = \text{Area}(A \cap B) / \text{Area}(A \cup B). Take box A [50,50,150,150][50, 50, 150, 150] and box B [100,100,200,200][100, 100, 200, 200]. Each covers 100×100=10,000100 \times 100 = 10{,}000. The overlap runs xx from 100 to 150 and yy from 100 to 150, so 50×50=2,50050 \times 50 = 2{,}500. Union is 10,000+10,000−2,500=17,50010{,}000 + 10{,}000 - 2{,}500 = 17{,}500. IoU is 2,500/17,500=1/7≈0.14292{,}500 / 17{,}500 = 1/7 \approx 0.1429. Below the usual 0.5 true-positive line, these count as different objects.

GIoU, DIoU and CIoU

Plain IoU gives zero gradient when boxes do not touch, stalling box regression. The upgrades fix that. GIoU subtracts the empty space in the smallest enclosing box: for the example above the enclosing [50,50,200,200][50, 50, 200, 200] covers 22,50022{,}500, so GIoU is 0.1429−(22,500−17,500)/22,500≈−0.07940.1429 - (22{,}500 - 17{,}500)/22{,}500 \approx -0.0794, still informative below zero. DIoU adds center-distance penalties for faster convergence, and CIoU adds aspect-ratio consistency for tighter finals. Use CIoU or DIoU as the regression loss and keep plain IoU for matching and evaluation.

Code

def compute_iou(box1: list, box2: list) -> float:    x1, y1 = max(box1[0], box2[0]), max(box1[1], box2[1])    x2, y2 = min(box1[2], box2[2]), min(box1[3], box2[3])    inter = max(0, x2 - x1) * max(0, y2 - y1)    a1 = (box1[2] - box1[0]) * (box1[3] - box1[1])    a2 = (box2[2] - box2[0]) * (box2[3] - box2[1])    return inter / (a1 + a2 - inter)
print(round(compute_iou([50, 50, 150, 150], [100, 100, 200, 200]), 4))  # -> 0.1429

Watch Out For

One threshold for all object sizes

IoU 0.5 on a 20-pixel object tolerates far sloppier absolute errors than on a 400-pixel one, yet teams judge both by the same line. The symptom is small-object scores that look fine and mean little. Report across thresholds, as COCO-style AP does, instead of a single number.

IoU loss on non-overlapping starts

Plain IoU as a regression loss gives exactly zero gradient when prediction and target are disjoint, freezing early training. The symptom is boxes that never move from initialization. Use GIoU, DIoU or CIoU for the loss while keeping IoU for decisions.

The Quick Version

  • IoU is overlap area divided by union area, 0 for disjoint boxes and 1 for identical ones.
  • Worked example: boxes offset by half their size score 1/7≈0.14291/7 \approx 0.1429.
  • GIoU, DIoU and CIoU add enclosing-box, distance and shape terms that train through misses.
  • Use IoU for matching and scoring, its upgrades for regression losses.