OpenCV/OpenCV 강좌

IOU Python 예제 코드

webnautes 2023. 10. 28. 05:40
반응형

IOU(Intersection over union) Python 예제 코드입니다.

 

2023. 6. 13  최초작성



코드에서 사용할 경계상자 정보입니다.

box1 = (0, 0, 100, 100)    # x,y,w,h

box2 = (0, 0, 50, 50)      # x,y,w,h

box3 = (150, 150, 50, 50)  # x,y,w,h

 



box1과 box2의 관계부터 살펴봅니다.

 

IOU는 두 경계 집합의 교집합 면적과 두 경계 집합의 합집합 면적의 비율을 구합니다.

 

box1과 box2의 IOU를 구합니다.

box1과 box2의 교집합 면적은 box2의 면적이고 box1과 box2의 합집합의 면적은 box1의 면적입니다.

즉, 50*50 / 100*100 = 2500 / 10000 = 0.25 입니다.



box1에 box2가 겹친 비율은 아래 수식으로 계산할 수 있습니다.  계산해보면 50*50 / 50*50 = 1.0 입니다. 



box1과 box3의 관계를 살펴봅니다.

 

box1과 box3의 IOU를 구하면 두 경계 집합의 교집합 면적이 0이라서 IOU는 0이 됩니다. 

box1에 box3이 겹친 비율도 두 경계 집합의 교집합 면적이 0이라서 0이 됩니다. 




전체 코드입니다.

def calculate_iou(box1, box2):
    x1, y1, w1, h1 = box1
    x2, y2, w2, h2 = box2
   
    x1_max, y1_max = x1 + w1, y1 + h1
    x2_max, y2_max = x2 + w2, y2 + h2

    # 두 개의 경계 상자가 겹치는 영역을 찾습니다.
    inter_x_min = max(x1, x2)
    inter_y_min = max(y1, y2)
    inter_x_max = min(x1_max, x2_max)
    inter_y_max = min(y1_max, y2_max)

    # 두 개의 경계 상자가 겹치는 영역의 면적을 계산합니다.
    if (inter_x_min < inter_x_max) and (inter_y_min < inter_y_max):
        intersection_area = (inter_x_max - inter_x_min) * (inter_y_max - inter_y_min)
    else:
        return 0.0

    # 두 개의 경계 상자의 면적을 각각 계산합니다.
    box1_area = w1 * h1
    box2_area = w2 * h2

    # 교집합/합집합의 비율인 IOU를 계산합니다.
    # iou는 0에서 1사이의 값을 가집니다.
    # 값이 0이면 두 경계 상자는 전혀 겹치지 않으며 값이 1이면 두 경계상자는 완벽하게 겹쳐집니다.
    iou = intersection_area / (box1_area + box2_area - intersection_area)
   
    return iou

def calculate_percentage_in_box(box1, box2):
    x1, y1, w1, h1 = box1
    x2, y2, w2, h2 = box2
   
    inter_x_min = max(x1, x2)
    inter_y_min = max(y1, y2)
    inter_x_max = min(x1 + w1, x2 + w2)
    inter_y_max = min(y1 + h1, y2 + h2)

    # 두 개의 경계 상자가 겹치는 영역의 면적을 계산합니다.
    if (inter_x_min < inter_x_max) and (inter_y_min < inter_y_max):
        intersection_area = (inter_x_max - inter_x_min) * (inter_y_max - inter_y_min)
    else:
        return 0.0

    # 두번째 경계 상자의 면적을 구합니다.
    box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
   
    # 첫번째 경계 상자와 두번째 경계 상자가 겹치는 면적과 두번째 경계 상자의 비율을 구합니다.
    percentage = intersection_area / box2_area
   
    return percentage


box1 = (0, 0, 100, 100)    # x,y,w,h
box2 = (0, 0, 50, 50)      # x,y,w,h
box3 = (150, 150, 50, 50# x,y,w,h

iou = calculate_iou(box1, box2)
percentage = calculate_percentage_in_box(box1, box2)

print(f"IOU : {iou}")
print(f"box1과 겹치는 box2의 비율 : {percentage}")
print()

iou = calculate_iou(box1, box3)
percentage = calculate_percentage_in_box(box1, box3)

print(f"IOU : {iou}")
print(f"box1과 겹치는 box3의 비율 : {percentage}")



실행결과입니다.

 

IOU : 0.25

box1과 겹치는 box2의 비율 : 1.0

 

IOU : 0.0

box1과 겹치는 box3의 비율 : 0.0




반응형