CyberPunk
CyberPunk

Reputation: 1447

Calculating IOU for bounding box predictions

enter image description here

I have these two bounding boxes as given in the image. the box cordinates are given as below :

box 1 = [0.23072851 0.44545859 0.56389928 0.67707491] box 2 = [0.22677664 0.38237819 0.85152483 0.75449795]

The coordinate are like this : ymin, xmin, ymax, xmax

I am calculating IOU as follows :

def get_iou(box1, box2):
    """
    Implement the intersection over union (IoU) between box1 and box2
        
    Arguments:
        box1 -- first box, numpy array with coordinates (ymin, xmin, ymax, xmax)
        box2 -- second box, numpy array with coordinates (ymin, xmin, ymax, xmax)
    """
    # ymin, xmin, ymax, xmax = box
    
    y11, x11, y21, x21 = box1
    y12, x12, y22, x22 = box2
    
    yi1 = max(y11, y12)
    xi1 = max(x11, x12)
    yi2 = min(y21, y22)
    xi2 = min(x21, x22)
    inter_area = max(((xi2 - xi1) * (yi2 - yi1)), 0)
    # Calculate the Union area by using Formula: Union(A,B) = A + B - Inter(A,B)
    box1_area = (x21 - x11) * (y21 - y11)
    box2_area = (x22 - x12) * (y22 - y12)
    union_area = box1_area + box2_area - inter_area
    # compute the IoU
    iou = inter_area / union_area
    return iou

Based on my understanding these 2 boxes completely overlap each other so IOU should be 1. However I get an IOU of 0.33193138665968164 . Is there something which I am doing wrong or I am interpreting it in an incorrect way. Any suggestions in this regard would be helpful.

Upvotes: 3

Views: 7687

Answers (2)

Sanchit
Sanchit

Reputation: 3289

You should not compute IOU value here as what others have explained above accurately. What you can do is to compute overlap area w.r.t smallest bounding box (see the logic below). It would provide a value on how much your smallest bounding box is overlapped/encapsulated inside of the largest bounding box. Thus, you will get the overlap value nearly 1.0 as what you are expecting in your question and it will be also bounded between [0.0, 1.0].

def get_overlap(box1, box2):
    """
    Implement the relative overlap between box1 and box2
            
    Arguments:
        box1 -- first box, numpy array with coordinates (ymin, xmin, ymax, xmax)
        box2 -- second box, numpy array with coordinates (ymin, xmin, ymax, xmax)
    """
    # ymin, xmin, ymax, xmax = box
    
    y11, x11, y21, x21 = box1
    y12, x12, y22, x22 = box2
    
    yi1 = max(y11, y12)
    xi1 = max(x11, x12)
    yi2 = min(y21, y22)
    xi2 = min(x21, x22)
    inter_area = max(((xi2 - xi1) * (yi2 - yi1)), 0)

    box1_area = (x21 - x11) * (y21 - y11)
    box2_area = (x22 - x12) * (y22 - y12)

    # compute the overlapped area w.r.t area of the smallest bounding box
    overlap = inter_area / min(box1_area, box2_area)
    return overlap

Upvotes: 0

ndrplz
ndrplz

Reputation: 1654

You are interpreting the IoU in an incorrect way.

If pay attention to your example, you notice that the union of the areas of the two bounding boxes is much bigger than the intersection of the areas. So it makes sense that the IoU - which is indeed intersection / union - is much smaller than one.

When you say

Based on my understanding these 2 boxes completely overlap each other so IOU should be 1.

that is not true. In your situation the two bounding boxes overlap only in the sense that one is completely contained in the other. But if this situation weren't penalized, IoU could be always maximized predicting a bounding box as big as the image - which clearly doesn't make sense.

Upvotes: 2

Related Questions