IOU交併比的計算

背景:在進行目標檢測時,常常會用到交併比的概念(IoU(Intersection over Union))

                                                             IoU=\frac{Area\, of\, Overlap}{Area\, of\, Union}

一般來說,這個IoU > 0.5 就可以被認爲是一個不錯的結果。

1.規則矩形框的IoU計算

有些目標檢測中,預測的邊界框爲規則的矩形,則只需要知道矩形的左上角和右下角的座標信息,就可以得到矩形框所有想要的信息。對於這種情況,IoU的python實現如下(python3.5)

def IoU(box1, box2):
    '''
    計算兩個矩形框的交併比
    :param box1: list,第一個矩形框的左上角和右下角座標
    :param box2: list,第二個矩形框的左上角和右下角座標
    :return: 兩個矩形框的交併比iou
    '''
    x1 = max(box1[0], box2[0])   # 交集左上角x
    x2 = min(box1[2], box2[2])   # 交集右下角x
    y1 = max(box1[1], box2[1])   # 交集左上角y
    y2 = min(box1[3], box2[3])   # 交集右下角y

    overlap = max(0., x2-x1) * max(0., y2-y1)
    union = (box1[2]-box1[0]) * (box1[3]-box1[1]) \
            + (box2[2]-box2[0]) * (box2[3]-box2[1]) \
            - overlap

    return overlap/union
if __name__ == '__main__':
    # box = [左上角x1,左上角y1,右下角x2,右下角y2]
    box1 = [10, 0, 15, 10]
    box2 = [12, 5, 20, 15]
    iou = IoU(box1, box2)

2. 非矩形框IoU計算

在有些目標檢測中,檢測框並不是規則的矩形框,例如自然場景下的文本檢測,有些呈現平行四邊形,梯形等情況,這時計算IoU時,就比較複雜一些。這時可以藉助於python的一些庫實現多邊形的面積計算

import shapely
import numpy as np
from shapely.geometry import Polygon, MultiPoint  # 多邊形

def bbox_iou_eval(box1, box2):
    '''
    利用python的庫函數實現非矩形的IoU計算
    :param box1: list,檢測框的四個座標[x1,y1,x2,y2,x3,y3,x4,y4]
    :param box2: lsit,檢測框的四個座標[x1,y1,x2,y2,x3,y3,x4,y4]
    :return: IoU
    '''
    box1 = np.array(box1).reshape(4, 2)  # 四邊形二維座標表示
    # python四邊形對象,會自動計算四個點,並將四個點重新排列成
    # 左上,左下,右下,右上,左上(沒錯左上排了兩遍)
    poly1 = Polygon(box1).convex_hull
    box2 = np.array(box2).reshape(4, 2)
    poly2 = Polygon(box2).convex_hull

    if not poly1.intersects(poly2):  # 如果兩四邊形不相交
        iou = 0
    else:
        try:
            inter_area = poly1.intersection(poly2).area  # 相交面積
            iou = float(inter_area) / (poly1.area + poly2.area - inter_area)
        except shapely.geos.TopologicalError:
            print('shapely.geos.TopologicalError occured, iou set to 0')
            iou = 0

    return iou

if __name__ == '__main__':
    # box = [四個點的座標,順序無所謂]
    box3 = [10, 0, 15, 0, 15, 10, 10, 10]   # 左上,右上,右下,左下
    box4 = [12, 5, 20, 2, 20, 15, 12, 15]
    iou = bbox_iou_eval(box3, box4)
    print(iou)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章