[OD] Intersection over Union (IoU)

Sinaenjuni·2024년 1월 10일
0

Object detection

목록 보기
1/4

Intersection over Union이란?

Object detection 과정에서 예측된 Bbox와 정답 Bbox간의 정확도를 평가하는 평가 지표 중 하나이다. 말 그대로 두 박스가 얼마나 겹치는 지를 가지고 수치적으로 표현한 것이다.

계산 방법은 생각보다 간간하다. 두 Bbox의 교집합을 합집합으로 나눠주는 것이다. 이렇게하면 0부터 1사이의 값으로 정규화된 값을 얻을 수 있다.

Bbox를 정의하는 좌표의 종류

이미지 상의 Bbox의 경우 좌상단과 우하단을 이용해서 표현하는 minmax 형태의 좌표 체계가 있고, Bbox의 중앙과 넓이, 높이를 통해 정의하는 xywh 형태의 좌표 체계가 있다.

minmax 형태의 좌표가 IoU 계산에 유리하다. 자세한 설명보다는 코드를 보면 쉽게 이해할 수 있을 것이다.

Implementation with Pytorch

def intersection_over_union(pred_bboxes, target_bboxes):
    if not torch.all(pred_bboxes[..., 0] < pred_bboxes[..., 2]) and \
        not torch.all(pred_bboxes[..., 1] < pred_bboxes[..., 3]):
        raise Exception("pred_bboxes box is not minmax type")

    if not torch.all(target_bboxes[..., 1] < target_bboxes[..., 3]) and \
        not torch.all(target_bboxes[..., 1] < target_bboxes[..., 3]):
        raise Exception("target_bboxes box is not minmax type")

    # minx, miny, maxx, maxy    
    minx = torch.max(pred_bboxes[..., 0], target_bboxes[..., 0])
    miny = torch.max(pred_bboxes[..., 1], target_bboxes[..., 1])
    maxx = torch.min(pred_bboxes[..., 2], target_bboxes[..., 2])
    maxy = torch.min(pred_bboxes[..., 3], target_bboxes[..., 3])
    intersection = (maxx - minx).clamp(0) * (maxy - miny).clamp(0)

    # w: maxx - minx, h:maxy - miny
    preds_area =   torch.abs((pred_bboxes[..., 2] - pred_bboxes[..., 0]) \
    * (pred_bboxes[..., 3] - pred_bboxes[..., 1]))
    targets_area = torch.abs((target_bboxes[..., 2] - target_bboxes[..., 0]) \
    * (target_bboxes[..., 3] - target_bboxes[..., 1]))
    union = (preds_area + targets_area - intersection + 1e-6)
    return intersection / union
def xywh2minmax(bboxes):
    ret = torch.zeros_like(bboxes).to(torch.float32)
    ret[..., 0] = bboxes[..., 0] - bboxes[..., 2] /2 # minx
    ret[..., 1] = bboxes[..., 1] - bboxes[..., 3] /2 # miny
    ret[..., 2] = bboxes[..., 0] + bboxes[..., 2] /2 # maxx
    ret[..., 3] = bboxes[..., 1] + bboxes[..., 3] /2 # maxy
    return ret
    
def xywh2minmax(bboxes):
    ret = torch.zeros_like(bboxes).to(torch.float32)
    ret[..., 0] = bboxes[..., 0] - bboxes[..., 2] /2 # minx
    ret[..., 1] = bboxes[..., 1] - bboxes[..., 3] /2 # miny
    ret[..., 2] = bboxes[..., 0] + bboxes[..., 2] /2 # maxx
    ret[..., 3] = bboxes[..., 1] + bboxes[..., 3] /2 # maxy
    return ret

References

  1. https://www.youtube.com/watch?v=XXYG5ZWtjj0&list=PLhhyoLH6Ijfw0TpCTVTNk42NN08H6UvNq&index=9

0개의 댓글