How does Intersection over Union (IoU) evaluate bounding box accuracy?
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.
IoU answers one question: how much do these two rectangles agree? The formula is just overlap divided by combined area.
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.0It 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.
Related questions
Stuck on this in a real project?
Book a free call and I’ll give you a straight answer on your specific case.
Book a consultation