Calculating IoU between oriented bounding boxes

Shikhar Gupta
Mindkosh AI
Published in
3 min readAug 7, 2024
Oriented bounding boxes provide a tighter fit around rotated objects, specially in aerial imagery

Oriented bounding boxes (OBB) are a type of bounding box where the bounding box enclosing an object can be rotated to better fit the object’s natural orientation. Compared with regular axis-aligned bounding boxes, Oriented bounding boxes can capture the exact orientation of the object, providing a tighter and more accurate fit.

OBBs can be especially useful in use-cases like detecting objects in satellite images which can contain a large number of naturally rotated objects.

Calculating Intersection over Union (IoU) for oriented bounding boxes (OBBs) involves determining the area of overlap between two OBBs and dividing it by the area of their union. Unlike axis-aligned bounding boxes, OBBs can be rotated, making the calculation more complex.

The basic idea is to convert the rotated bounding boxes into polygons and calculate the areas with respect to these polygons.

To calculate the IoU for OBBs, follow these steps:

Represent the OBBs
Bounding boxes are usually represented using the top-left and bottom right corners. However for this tutorial, we will represent an oriented bounding box by its center (cx, cy), width (w), height (h), and orientation angle θ.

Calculate the corners of each OBB
Next we calculate the final co-ordinates of the oriented bounding box after it has been rotated.

This gives us the co-ordinates of the 4 corners in clockwise direction starting from top-left corner. So the corners array contains [top-left corner, top-right corner, bottom-right corner, bottom-left corner]

Compute the polygon intersection
If you are writing your own code from scratch, you can use algorithms such as the Sutherland-Hodgman algorithm to find the intersection polygon of the two OBBs.

If you are instead free to use external libraries, use a library such as Shapely in Python, which can handle the intersection of polygons.

Calculate the area of the intersection polygon:

If using shapely, the intersection area can be calculated as simply as:


# obb1 and obb2 are the oriented bounding boxes
intersection_area = obb1.intersection(obb2).area

Calculate the area of each OBB
The area of a bounding box, whether rotated or not, is simply the product of its width and height:

Calculate the combined area of the OBBs
The union area is given by the formula:

Calculate IoU:
We are now ready to calculate the IoU

Here is a sample python code to do all these operations:

from shapely.geometry import Polygon
from shapely.affinity import rotate, translate

def create_obb(cx, cy, w, h, theta):
# Define the initial rectangle
rectangle = Polygon([(-w/2, -h/2), (w/2, -h/2), (w/2, h/2), (-w/2, h/2)])
# Rotate and translate the rectangle
rotated_rect = rotate(rectangle, theta, use_radians=True)
obb = translate(rotated_rect, cx, cy)
return obb

# Define the OBBs
obb1 = create_obb(cx1, cy1, w1, h1, theta1)
obb2 = create_obb(cx2, cy2, w2, h2, theta2)

# Calculate the intersection area
intersection_area = obb1.intersection(obb2).area

# Calculate the union area
union_area = obb1.area + obb2.area - intersection_area

# Calculate IoU
iou = intersection_area / union_area

print(f"IoU: {iou}")

--

--