Python极简实现IoU

IoU概念

交并比(Intersection-over-Union,IoU),就是交集与并集的比值,是在目标检测中常用的算法。

IoU简图

分子部分就是Box1与Box2交集的面积,先设为A1。分母部分是Box1与Box2并集集的面积,设为A2,其实也是Box1面积S1加上Box2面积S2再减去一个A1,即:
I o U = A 1 A 2 A 2 = S 1 + S 2 − A 1 I o U = A 1 S 1 + S 2 − A 1 IoU = \frac{A1}{A2}\\[5pt] A2 = S1 + S2 - A1\\[5pt] IoU = \frac{A1}{S1+S2-A1} IoU=A2A1A2=S1+S2A1IoU=S1+S2A1A1
问题就转化为对Box与A1的求解。

交集的坐标系表示
如上图,为了求交集面积,只要知道上图中两个蓝色点的坐标(或另外两个角坐标)即可。

Box的表示与计算

Box有常用的两种表达方式:

COCO与VOC数据集: b o x a = ( x m i n , y m i n , x m a x , y m a x ) box_a = (x_{min},y_{min},x_{max},y_{max}) boxa=(xmin,ymin,xmax,ymax)

YOLO格式: b o x b = ( x c e n t e r , y c e n t e r , w , h ) box_b = (x_{center},y_{center},w,h) boxb=(xcenter,ycenter,w,h)

两种格式的转换关系如下:
x m i n , y m i n , x m a x , y m a x = r o u n d ( x c e n t e r − ( w / 2.0 ) ) , r o u n d ( y c e n t e r − ( h / 2.0 ) ) , r o u n d ( x c e n t e r + ( w / 2.0 ) ) , r o u n d ( y c e n t e r + ( h / 2.0 ) ) x c e n t e r , y c e n t e r , w , h = r o u n d ( ( x m i n + x m a x ) / 2.0 ) , r o u n d ( ( y m i n + y m a x ) / 2.0 ) , r o u n d ( x m a x − x m i n ) , r o u n d ( y m a x − y m i n ) b o x a = ( r o u n d ( b o x b [ 0 ] − ( b o x b [ 2 ] / 2.0 ) ) , r o u n d ( b o x b [ 1 ] − ( b o x b [ 3 ] / 2.0 ) , r o u n d ( b o x b [ 0 ] + ( b o x b [ 2 ] / 2.0 ) , r o u n d ( b o x b [ 1 ] + ( b o x b [ 3 ] / 2.0 ) ) x_{min},y_{min},x_{max},y_{max} = round(x_{center}-(w/2.0)),round(y_{center}-(h/2.0)),round(x_{center}+(w/2.0)),round(y_{center}+(h/2.0))\\[5pt] x_{center},y_{center},w,h = round((x_{min}+x_{max})/2.0),round((y_{min}+y_{max})/2.0),round(x_{max}-x_{min}),round(y_{max}-y_{min})\\[5pt] box_a = (round(box_b[0]-(box_b[2]/2.0)) ,round(box_b[1]-(box_b[3]/2.0),round(box_b[0]+(box_b[2]/2.0),round(box_b[1]+(box_b[3]/2.0)) xmin,ymin,xmax,ymax=round(xcenter(w/2.0)),round(ycenter(h/2.0)),round(xcenter+(w/2.0)),round(ycenter+(h/2.0))xcenter,ycenter,w,h=round((xmin+xmax)/2.0),round((ymin+ymax)/2.0),round(xmaxxmin),round(ymaxymin)boxa=(round(boxb[0](boxb[2]/2.0)),round(boxb[1](boxb[3]/2.0),round(boxb[0]+(boxb[2]/2.0),round(boxb[1]+(boxb[3]/2.0))
box的面积计算:
S a = ( x m a x − x m i n ) ∗ ( y m a x − y m i n ) = ( b o x a [ 2 ] − b o x a [ 0 ] ) ∗ ( b o x a [ 3 ] − b o x a [ 1 ] ) S b = w ∗ h = b o x b [ 2 ] ∗ b o x b [ 3 ] S_a = (x_{max}-x_{min})*(y_{max}-y_{min}) = (box_a[2]-box_a[0])*(box_a[3]-box_a[1])\\[5pt] S_b = w*h = box_b[2]*box_b[3] Sa=(xmaxxmin)(ymaxymin)=(boxa[2]boxa[0])(boxa[3]boxa[1])Sb=wh=boxb[2]boxb[3]

A1交集情况

A1交集的多种情况
计算相交的面积只需计算出相交框的w与h。相交时有:

left = max(left1, left2)#相交框left是两个框的左上角x坐标的最大值
top = max(top1, top2)#相交框top是两个框的左上角y坐标的最大值
right =min(right1, right2)#相交框right是两个框的右下角x坐标的最大值
bottom =min(bottom1, bottom2)#相交框bottom是两个框的右下角y坐标的最大值

不相交时如情况5和6,w、h中至少有一个值等于0,使得计算面积A1也为0。即可表示为:

w = max(0, right - left)
h = max(0, bottom - top)

所以,计算IoU的代码可以如下:

def cal_iou(box1, box2):
    """
    :param box1: = [left1, top1, right1, bottom1]
    :param box2: = [left2, top2, right2, bottom2]
    :return: 
    """
    left1, top1, right1, bottom1 = box1
    left2, top2, right2, bottom2 = box2
    # 计算每个矩形的面积
    s1 = (right1 - left1) * (bottom1 - top1)  # b1的面积
    s2 = (right2 - left2) * (bottom2 - top2)  # b2的面积
 
    # 计算相交矩形
    left = max(left1, left2)
    top = max(top1, top2)
    right = min(right1, right2)
    bottom = min(bottom1, bottom2)
 
    # 相交框的w,h
    w = max(0, right - left)
    h = max(0, bottom - top)
    a1 = w * h  # C∩G的面积
    a2 = s1 + s2 - a1
    iou = a1 / a2 #iou = a1/ (s1 + s2 - a1)
    return iou

参考:
Python极简实现IoU

猜你喜欢

转载自blog.csdn.net/wq_0708/article/details/121422466
今日推荐