Skip to content

Instantly share code, notes, and snippets.

@JanSellner
Forked from meyerjo/iou.py
Last active June 24, 2020 16:00
Show Gist options
  • Save JanSellner/4dcd93f87ca2857e8cedc0344473a0d9 to your computer and use it in GitHub Desktop.
Save JanSellner/4dcd93f87ca2857e8cedc0344473a0d9 to your computer and use it in GitHub Desktop.
Python code to compute the intersection of two boundingboxes
from typing import Tuple
def intersection_over_union(boxA: Tuple[float, float, float, float], boxB: Tuple[float, float, float, float]) -> float:
"""Calculates the intersection of union between two rectangles/bounding boxes.
See https://www.pyimagesearch.com/2016/11/07/intersection-over-union-iou-for-object-detection/ for more information about IOU.
Args:
boxA: First bounding box with coordinates in the format [xmin, ymin, xmax, ymax].
boxB: Second bounding box with coordinates in the format [xmin, ymin, xmax, ymax].
Returns:
IOU in the range [0, 1] = [no intersection, complete intersection].
"""
xminA, yminA, xmaxA, ymaxA = boxA
xminB, yminB, xmaxB, ymaxB = boxB
# Fix possible missordering
if xminA > xmaxA:
xminA, xmaxA = xmaxA, xminA
if yminA > ymaxA:
yminA, ymaxA = ymaxA, yminA
if xminB > xmaxB:
xminB, xmaxB = xmaxB, xminB
if yminB > ymaxB:
yminB, ymaxB = ymaxB, yminB
# Determine the (x, y)-coordinates of the intersection rectangle
xA = max(xminA, xminB)
yA = max(yminA, yminB)
xB = min(xmaxA, xmaxB)
yB = min(ymaxA, ymaxB)
# Compute the area of intersection rectangle
interArea = abs(max((xB - xA, 0)) * max((yB - yA), 0))
if interArea == 0:
return 0
# Compute the area of both the prediction and ground-truth rectangles
boxAArea = abs((xmaxA - xminA) * (ymaxA - yminA))
boxBArea = abs((xmaxB - xminB) * (ymaxB - yminB))
# Compute the intersection over union by taking the intersection area and dividing it by the sum of prediction + ground-truth areas - the interesection area
iou = interArea / float(boxAArea + boxBArea - interArea)
return iou
if __name__ == '__main__':
# Pointing out a wrong IoU implementation in https://www.pyimagesearch.com/2016/11/07/intersection-over-union-iou-for-object-detection/
boxA = [0., 0., 10., 10.]
boxB = [1., 1., 11., 11.]
correct = intersection_over_union(boxA, boxB)
print('Correct solution - also analytical: {0}\n'
'Solution by published function: {1}\n'
'Solution by correction (ptyshevs): {2}'.format(correct, '0.704225352113', '0.680672268908'))
print('Normalizing coordinates in a 100x100 coordinate system')
boxA = [a / 100. for a in boxA]
boxB = [b / 100. for b in boxB]
correct = intersection_over_union(boxA, boxB)
print('Correct solution - also analytical: {0}\n'
'Solution by published function: {1}\n'
'Solution by correction: {2}'.format(correct, '0.964445166004', '0.680672268908'))
print('Two boxes with no overlap')
boxA = [0., 0., 10., 10.]
boxB = [12., 12., 22., 22.]
correct = intersection_over_union(boxA, boxB)
print('Correct solution - also analytical: {0}\n'
'Solution by published function: {1}\n'
'Solution by correction (ptyshevs): {2}'.format(correct, '0.0', '0.0204081632653'))
print('Example in the comments from ptyshevs')
boxA = [0., 0., 2., 2.]
boxB = [1., 1., 3., 3.]
correct = intersection_over_union(boxA, boxB)
print('Correct solution - also analytical: {0}\n'
'Solution by published function: {1}\n'
'Solution by correction (ptyshevs): {2}'.format(correct, '0.285714285714', '0.142857142857'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment