EasyMetrics & Evaluation

Intersection over Union (IoU)

Metrics & Evaluation · Computer Vision

Easy

Problem

Compute Intersection over Union for two axis-aligned boxes. Each box is given as [x_1,y_1,x_2,y_2], where the first point is the top-left corner and the second is the bottom-right corner.

A_{\mathrm{intersection}}=\max(0,x_R-x_L)\max(0,y_B-y_T)

A_{\mathrm{union}}=A_A+A_B-A_{\mathrm{intersection}}

\operatorname{IoU}=\frac{A_{\mathrm{intersection}}}{A_{\mathrm{union}}}

Here, x_L and y_T are the largest starting coordinates, while x_R and y_B are the smallest ending coordinates. Return zero when the union is zero. Otherwise return IoU as a Python float.

Theory

Intersection over Union (IoU), also called the Jaccard index, measures how much two regions overlap:

\text{IoU} = \frac{|A \cap B|}{|A \cup B|} = \frac{\text{Area of Intersection}}{\text{Area of Union}}

For bounding boxes:


IoU Range and Interpretation

IoU ranges from 0 to 1:

IoU = 0: No overlap at all. The boxes are completely separate. IoU = 0.5: Moderate overlap. Often used as a threshold for "correct" detection. IoU = 0.75: Good overlap. Used for stricter evaluation (COCO AP75). IoU = 1.0: Perfect overlap. Boxes are identical.

Common thresholds in object detection:


Computing IoU for Axis-Aligned Boxes

Given two boxes defined by (x1, y1, x2, y2) where (x1, y1) is top-left and (x2, y2) is bottom-right:

Step 1: Find intersection coordinates

Step 2: Compute intersection area

Step 3: Compute union area

Step 4: Compute IoU


Numerical Example

Box A (predicted): x1=100, y1=100, x2=200, y2=200 Box B (ground truth): x1=120, y1=110, x2=220, y2=210

Intersection:

Areas:

IoU: 7200 / 12800 = 0.5625


IoU as a Loss Function

Using IoU directly as a loss:

L_{\text{IoU}} = 1 - \text{IoU}

This loss is 0 when boxes perfectly overlap and 1 when they do not overlap at all.

Advantages:

Disadvantage:


The Non-Overlapping Problem

Consider two non-overlapping boxes:

IoU = 0, so IoU loss = 1.

Now move Box A slightly right:

Still no overlap, IoU = 0, loss = 1.

The gradient is zero! The model receives no signal about which direction to move. This is a critical limitation of vanilla IoU loss.


GIoU: Generalized IoU

GIoU (Generalized Intersection over Union) fixes the non-overlapping problem:

\text{GIoU} = \text{IoU} - \frac{|C - (A \cup B)|}{|C|}

Where C is the smallest enclosing box that contains both A and B.

Key insight: even when boxes do not overlap, the enclosing box C changes as boxes move. This provides gradient signal.

GIoU range: [-1, 1]

Loss: L_{\text{GIoU}} = 1 - \text{GIoU}


DIoU and CIoU

DIoU (Distance IoU): adds penalty for center distance

\text{DIoU} = \text{IoU} - \frac{d^2}{c^2}

Where:

This directly encourages boxes to have similar centers.

CIoU (Complete IoU): adds penalty for aspect ratio difference

\text{CIoU} = \text{IoU} - \frac{d^2}{c^2} - \alpha v

Where:

CIoU considers overlap, center distance, and shape similarity.


Comparison of IoU Variants

Vanilla IoU:

GIoU:

DIoU:

CIoU:


The Gradient of IoU

For IoU loss, the gradient with respect to box coordinates is non-trivial because it involves min/max operations.

For predicted box coordinates (x1, y1, x2, y2):

Modern deep learning frameworks handle this automatically through autograd.


Where IoU Loss Is Used

Best practices:

Examples

Example 1

Input
box_a = [0, 0, 4, 4], box_b = [2, 2, 6, 6]
Output
0.142857
Explanation
The intersection area is 4 and the union area is 28.

Example 2

Input
box_a = [0, 0, 2, 2], box_b = [3, 3, 5, 5]
Output
0

Hints

  1. Use maximum starting coordinates and minimum ending coordinates for the intersection.
  2. Compute union with area_a + area_b - intersection.

Requirements

Constraints

Starter Code

def iou(box_a: list, box_b: list) -> float:
    """
    Returns IoU as a float.
    """
    # Write code here
    pass

Test Cases

CaseMatches
Partial overlappublic
No overlappublic