OpenCV 비전 실무18장 · OpenCV 전처리와 YOLO 연계8 / 21← 이전목차다음 →MetaContents

18장. OpenCV 전처리와 YOLO 연계

맞혔는지 재기

과녁에 화살을 쏘면 정중앙에 꽂히지 않아도 과녁 안에만 들면 점수를 줍니다. 상자도 정답과 칸 하나까지 똑같을 수는 없습니다. 그래서 "얼마나 겹쳤나"를 재서 기준 이상이면 맞힌 것으로 칩니다. 겹친 정도를 재는 값이 IoU 입니다.

정답 상자와 찾은 상자가 겹친 넓이를 합친 넓이로 나눈 IoU 를 숫자 상자 두 쌍으로 손계산한 그림

초록 실선이 정답 상자, 다홍 점선이 찾은 상자, 청록으로 칠한 곳이 겹친 부분입니다. 왼쪽은 많이 겹쳐 IoU 가 0.538 이고, 오른쪽은 조금만 겹쳐 0.111 입니다. 여기서 과녁이 정답 상자, 화살이 찾은 상자, "과녁 안에 들었나"가 IoU 0.5 기준입니다.

IoU 손으로 계산하기

왼쪽 그림의 숫자로 계산합니다. 정답은 (40, 40, 140, 120), 찾은 상자는 (60, 50, 160, 130) 입니다.

구할 것식계산값
정답의 넓이너비 × 높이(140 − 40) × (120 − 40) = 100 × 808000
찾은 상자의 넓이너비 × 높이(160 − 60) × (130 − 50) = 100 × 808000
겹친 너비작은 오른쪽 끝 − 큰 왼쪽 끝min(140, 160) − max(40, 60) = 140 − 6080
겹친 높이작은 아래 끝 − 큰 위 끝min(120, 130) − max(40, 50) = 120 − 5070
겹친 넓이겹친 너비 × 겹친 높이80 × 705600
합친 넓이두 넓이의 합 − 겹친 넓이8000 + 8000 − 560010400
IoU겹친 넓이 ÷ 합친 넓이5600 ÷ 104000.538

합친 넓이에서 겹친 넓이를 한 번 빼는 까닭은, 두 넓이를 더하면 겹친 곳이 두 번 세어지기 때문입니다. IoU 는 두 상자가 똑같으면 1, 전혀 안 겹치면 0 입니다.

짝짓고 세기

사진 한 장에서 찾은 상자들과 정답 상자들을 짝짓습니다. 신뢰도가 높은 찾은 상자부터, 아직 짝이 없는 같은 클래스의 정답 가운데 IoU 가 가장 큰 것과 짝짓습니다. 그 IoU 가 0.5 이상이면 맞힌 것입니다.

맞힌 것, 헛것, 놓친 것의 세 가지를 나란히 놓은 비교 그림

그림의 세 카드가 짝짓기를 마친 뒤 세는 세 가지입니다. 11장의 그물 비유로 말하면, 맞힌 것은 그물에 걸린 물고기, 헛것은 그물에 걸린 깡통, 놓친 것은 그물을 빠져나간 물고기입니다. 점수는 11장에서 본 것과 같은 식으로 냅니다.

점수식뜻
정밀도맞힌 것 ÷ (맞힌 것 + 헛것)찾은 상자 가운데 맞은 비율
재현율맞힌 것 ÷ (맞힌 것 + 놓친 것)정답 가운데 찾아낸 비율
F12 × 정밀도 × 재현율 ÷ (정밀도 + 재현율)둘을 하나로 합친 점수
Python
def iou(a, b):
    """두 상자 (x1, y1, x2, y2) 의 IoU = 겹친 넓이 ÷ 합친 넓이."""
    w = min(a[2], b[2]) - max(a[0], b[0])        # 겹친 너비(음수면 안 겹침)
    h = min(a[3], b[3]) - max(a[1], b[1])        # 겹친 높이
    inter = max(0, w) * max(0, h)
    union = (a[2] - a[0]) * (a[3] - a[1]) + (b[2] - b[0]) * (b[3] - b[1]) - inter
    return inter / union

print(round(iou((40, 40, 140, 120), (60, 50, 160, 130)), 3))    # 결과: 0.538
print(round(iou((40, 40, 140, 120), (100, 80, 200, 160)), 3))   # 결과: 0.111

# 맞힌 것 3, 헛것 1, 놓친 것 2 일 때의 점수
tp, fp, fn = 3, 1, 2
precision, recall = tp / (tp + fp), tp / (tp + fn)
print(round(precision, 3), round(recall, 3), round(2 * precision * recall / (precision + recall), 3))

맞힌 것 3, 헛것 1 이면 정밀도는 3 ÷ 4 = 0.75, 놓친 것이 2 면 재현율은 3 ÷ 5 = 0.6 입니다. F1 은 2 × 0.75 × 0.6 ÷ 1.35 = 0.667 로, 11장의 그물 예와 같은 값이 나옵니다.

주의할 점

  • 정답 하나에 찾은 상자 둘이 겹치면, 먼저 짝지은 하나만 맞힌 것이고 나머지는 헛것입니다. 정답 하나에 점수를 두 번 주지 않습니다.
  • 상자가 잘 겹쳐도 클래스가 다르면(너트를 와셔라고 하면) 맞힌 것이 아닙니다. 그 상자는 헛것이 되고, 그 정답은 놓친 것이 됩니다.
← 이전 절18장 · 추론 결과 다루기다음 절 →18장 · 전처리가 결과에 주는 영향