Intersection over Union

마이클의 AI 연구소·2022년 2월 8일
0
post-thumbnail

개요

IoU란 Intersection over Union의 약자로 말그대로 두 영역의 겹치는 영역을 두 영역의 합으로 나눈 값을 의미합니다. 따라서 두 영역이 완전히 겹친다면 겹치는 영역과 합의 영역이 동일하므로 1이 되고, 전혀 겹치지 않는다면 0이 됩니다.

IoU는 주로 Object Detection에서 예측된 bounding box의 정확도를 평가하는 지표 중 하나로 사용됩니다. 일반적으로 임계값을 지정하여 해당 임계값을 초과하는 경우에는 해당 위치에 대한 예측을 유효한 것으로 간주합니다. 논문 등에서 객체탐지 성능평가표에 mAP@0.5로 표기되었다면 IoU 임계값을 0.5로 설정했다는 의미입니다. 임계값을 높이면 더 정밀하게 일치한 예측만을 맞는 것으로 간주하는 것이므로 전체적인 성능평가 수치는 하락할 것입니다.

구현

실제 데이터로 IoU를 계산하는 로직을 구현해봅시다.

gt.json 파일에는 여러 이미지의 ground-truth 데이터의 boudning box와 class 정보가 포함되어 있습니다. dictionary 형태 데이터로 key-value 형식입니다. 실제 데이터는 다음과 같습니다.

{"boxes": [[793, 1134, 1001, 1718], [737, 0, 898, 260], [763, 484, 878, 619], [734, 0, 1114, 277], [853, 0, 1280, 250], [820, 1566, 974, 1914], [762, 951, 844, 1175], [748, 197, 803, 363]], "classes": [1, 1, 1, 1, 2, 1, 1, 1], "filename": "0001.png"}, 

pred.json 파일에는 예측한 데이터의 bounding box와 class 정보가 포함되어 있습니다.

{"boxes": [[783, 1104, 1011, 1700], [853, 0, 1220, 200], [734, 0, 1100, 240], [753, 474, 868, 609], [830, 1500, 1004, 1914]], "classes": [1, 2, 1, 2, 1], "filename": "0001.png"},

먼저 json을 로드합니다.

with open('qt.json) as f:
	ground_truth = json.load(f)
    
with open('pred.json) as f:
	predictions = json.load(f)

예측 데이터 중 지금 측정하려고 하는 특정 이미지(0001.png)에 대한 ground-truth와 prediction의 bounding box들을 numpy array 형태로 추출합니다.

gt_bboxes = np.array([g['boxes'] for g in ground_truth if g['filename'] == '0001.png'][0])
pred_bboxes = np.array([p['boxes'] for p in predictions if p['filename'] == '0001.png'][0])

추출한 numpy array를 순회하면서 각 박스들의 IoU를 계산합니다.

def calculate_ious(gt_bboxes, pred_bboxes):
    ious = np.zeros((gt_bboxes.shape[0], pred_bboxes.shape[0]))
    for i, gt_bbox in enumerate(gt_bboxes):
        for j, pred_bbox in enumerate(pred_bboxes):
            ious[i,j] = calculate_iou(gt_bbox, pred_bbox)
    return ious

def calculate_iou(gt_bbox, pred_bbox):
    box1_area = (gt_bbox[2]-gt_bbox[0]) * (gt_bbox[3]-gt_bbox[1])
    box2_area = (pred_bbox[2]-pred_bbox[0]) * (pred_bbox[3]-pred_bbox[1])
    
    # intersection box
    x1 = max(gt_bbox[0], pred_bbox[0])
    y1 = max(gt_bbox[1], pred_bbox[1])
    x2 = min(gt_bbox[2], pred_bbox[2])
    y2 = min(gt_bbox[3], pred_bbox[3])
    
    w = max(x2-x1, 0)
    h = max(y2-y1, 0)
    
    if w > 0 and h > 0:
        intersect = w*h
        iou = intersect / (box1_area + box2_area - intersect)
    else:
        iou = 0

    return iou
profile
늘 성장을 꿈꾸는 자들을 위한 블로그입니다.

0개의 댓글