-
-
Save JanSellner/4dcd93f87ca2857e8cedc0344473a0d9 to your computer and use it in GitHub Desktop.
Python code to compute the intersection of two boundingboxes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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