이 포스트에서는 두 사각형의 IOU를 구하는 방법을 설명하겠습니다.


개요

IOU(Intersection over union)이란 두 영역의 교차영역의 넓이를 합영역의 값으로 나눈 값을 뜻합니다. 객체 검출에서 예측된 경계 상자의 정확도를 평가하는 지표 중 하나로 사용되며, 예측된 경계 상자와 실제 참값(ground truth) 경계 상자의 IOU를 해당 경계 상자의 ‘정확도’로 간주합니다. 객체 검출 모델의 정확도는 모델을 테스트용 데이터셋에서 실행해본 다음 정밀도-재현율 곡선(precision-recall curve)과 평균 정밀도(average precision)를 구해 수치화할 수 있는데, 이 과정에서 IOU 값이 사용됩니다.


회전 없는 사각형의 IOU 계산

iou of non-rotated rectangle

회전 없는 직사각형의 IOU를 생각해 볼 수 있습니다.

def intersection_over_union(box1, box2):
    x1 = max(box1[0], box2[0])
    y1 = max(box1[1], box2[1])
    x2 = min(box1[2], box2[2])
    y2 = min(box1[3], box2[3])

먼저 겹치는 영역의 꼭지점 좌표를 구합니다. 각 사각형의 꼭지점 중에 좀 더 ‘안쪽’에 있는 꼭지점만 고르면 됩니다. 즉 왼쪽 x 좌표와 위쪽 y 좌표는 둘 중에 큰 값을 선택하고, 오른쪽 x 좌표와 아래쪽 y 좌표는 둘 중에 작은 값을 선택합니다.

    area_intersection = (x2 - x1) * (y2 - y1)
    area_box1 = (box1[2] - box1[0]) * (box1[3] - box1[2])
    area_box2 = (box2[2] - box2[0]) * (box2[3] - box2[2])
    area_union = area_box1 + area_box2 - area_intersection

이제 합 영역과 교차 영역의 넓이를 구합니다. 합 영역은 두 사각형의 넓이의 합에서 교차 영역의 넓이를 빼면 됩니다.

    iou = area_intersection / area_union
    return iou

마지막으로 구한 영역 값을 이용해 IOU 값을 계산하고 반환합니다.


다른 경우의 IOU 계산

회전이 있는 사각형일 경우도 있고, 아예 사각형이 아닌 경우도 있습니다. 교차 영역의 넓이와 두 도형의 넓이를 알면 IOU를 바로 구할 수 있는데 위 코드의 단순한 계산을 사용할 수 없으므로 계산이 복잡해집니다. 일반적인 해법은 없으며 각 경우에 맞춰 독립적으로 알고리즘을 수립해야 합니다. 볼록 다각형일 때의 일반적인 해법은 아래와 같습니다. 객체 인식과 직접적인 관련이 없는 심화이므로 코드 없이 간단히 원리만 설명하겠습니다.

  1. 두 다각형의 교점을 모두 구합니다.
  2. 교점을 모두 포함하는 최소 볼록 껍질(convex hull)을 구합니다.
  3. 두 다각형과 볼록 껍질의 영역 넓이를 신발끈 공식을 이용하여 구합니다.