IoU(Intersection over Union)
在目标检测任务中,IoU是一个非常重要的概念,它反映了prediction box和ground truth box的贴合程度。在用训练好的模型进行测试时,网络会预测出一系列的prediction box,这时候我们会用NMS来移除一些多余的候box,即移除一些IoU值大于某个阈值的box,然后在剩下的box中,分别计算与ground truth的IoU值,通常会规定当候选框和ground truth的IoU值大于0.5时,认为检测正确。
IoU
概念
IoU是由旷视科技提出的一种让目标检测用上定位置信度的方法,paper发表于2018年的顶会ECCV。IoU的概念来源于数学中的集合,用来描述两个集合A和B之间的关系,它等于两个集合的交集里面所包含的元素个数除以并集里面所包含的元素个数,具体的计算公式: I o U = A ∩ B A ∪ B I o U=\frac{A \cap B}{A \cup B} IoU=A∪BA∩B。我们将用这个概念来描述两个box之间的重合度,将两个box可以看成是两个像素的集合,它们的IoU等于两个框重合部分的面积除以它们合并起来的面积。
假设两个矩形框A和B的位置分别为: A : [ x a 1 , y a 1 , x a 2 , y a 2 ] B : [ x b 1 , y b 1 , x b 2 , y b 2 ] \begin{array}{l} A:\left[x_{a 1}, y_{a 1}, x_{a 2}, y_{a 2}\right] \\ B:\left[x_{b 1}, y_{b 1}, x_{b 2}, y_{b 2}\right] \end{array} A:[xa1,ya1,xa2,ya2]B:[xb1,yb1,xb2,yb2]
如果二者有相交部分,则相交部分左上角坐标为: x 1 = max ( x a 1 , x b 1 ) , y 1 = max ( y a 1 , y b 1 ) x_{1}=\max \left(x_{a 1}, x_{b 1}\right), \quad y_{1}=\max \left(y_{a1}, y_{b 1}\right) x1=max(xa1,xb1),y1=max(ya1,yb1)
相交部分右下角坐标为: x 2 = min ( x a 2 , x b 2 ) , y 2 = min ( y a 2 , y b 2 ) x_{2}=\min \left(x_{a2}, x_{b2}\right), \quad y_{2}=\min \left(y_{a2}, y_{b2}\right) x2=min(xa2,xb2),y2=min(ya2,yb2)
计算先交部分面积: intersection = max ( x 2 − x 1 , 0 ) ⋅ max ( y 2 − y 1 , 0 ) \text { intersection }=\max \left(x_{2}-x_{1},0\right) \cdot \max \left(y_{2}-y_{1},0\right) intersection =max(x2−x1,0)⋅max(y2−y1,0)
矩形框A和B的面积分别是: S A = ( x a 2 − x a 1 ) ⋅ ( y a 2 − y a 1 ) S B = ( x b 2 − x b 1 ) ⋅ ( y b 2 − y b 1 ) \begin{array}{l} S_{A}=\left(x_{a2}-x_{a1}\right) \cdot\left(y_{a2}-y_{a1}\right) \\ S_{B}=\left(x_{b2}-x_{b1}\right) \cdot\left(y_{b2}-y_{b1}\right) \end{array} SA=(xa2−xa1)⋅(ya2−ya1)SB=(xb2−xb1)⋅(yb2−yb1)
计算相并部分面积: union = S A + S B − intersection \text { union }=S_{A}+S_{B}-\text { intersection } union =SA+SB− intersection
计算IoU: I o U = intersection union I o U=\frac{\text { intersection }}{\text { union }} IoU= union intersection
Code
def area(box):
"""
计算 box 的面积,box 的坐标形式为 xyxy
"""
x1, y1, x2, y2 = box
return (max(x1, x2) - min(x1, x2)) * (max(y1, y2) - min(y1, y2))
def IoU(box1, box2):
"""
计算两个 box 的 IoU,box 的坐标形式为 xyxy
"""
s1 = area(box1)
s2 = area(box2)
x1, y1 = max(box1[0], box2[0]), max(box1[1], box2[1])
x2, y2 = max(box1[2], box2[2]), max(box1[3], box2[3])
intersection = max(x2 - x1, 0) * max(y2 - y1, 0)
union = s1 + s2 - intersection
return intersection / union
bbox1 = [100, 100, 200, 200]
bbox2 = [120, 120, 200, 200]
print(f"Iou = {iou(bbox1, bbox2)}")
缺陷
- 如果两个框没有相交,根据定义,IoU=0,因此如果两个box相距很远,IoU不能反映两者的距离大小;
- IoU无法精确的反映两者的重合度大小;
GIoU
针对IoU的缺陷,在CVPR 2019中,提出了GIoU的思想。
概念
GIoU的公式也很简单: G I o U = I o U − ∣ A c − U ∣ ∣ A c ∣ G I o U=I o U-\frac{\left|A_{c}-U\right|}{\left|A_{c}\right|} GIoU=IoU−∣Ac∣∣Ac−U∣,其实就是在IoU的基础上加了一个惩罚项。首先计算出两个box的最小闭包区域面积(同时包含了预测框和真实框的最小框的面积),然后计算出IoU,之后计算闭包区域中不属于两个框的区域占闭包区域的比重,最后用IoU减去这个比重得到GIoU。
Code
def GIoU(box1, box2):
"""
计算两个 box 的 GIoU,box 的坐标形式为 xyxy
"""
area1 = area(box1)
area2 = area(box2)
sumArea = area1 + area2
xa1, ya1, xa2, ya2 = box1
xb1, yb1, xb2, yb2 = box2
C = (max(xa1, xa2, xb1, xb2) - min(xa1, xa2, xb1, xb2)) * (max(ya1, ya2, yb1, yb2) - min(ya1, ya2, yb1, yb2))
x1, y1 = max(xa1, xb1), max(ya1, yb1)
x2, y2 = min(xa2, xb2), min(ya2, yb2)
intersection = max(x2 - x1, 0) * max(y2 - y1, 0)
union = sumArea - intersection
difference = C - union
iou = IoU(box1, box2)
return iou - difference / C
IoU取值[0,1],但GIoU有对称区间,取值范围[-1,1]。在两者重合的时候取最大值1,在两者无交集且无限远的时候取最小值-1,因此GIoU是一个非常好的距离度量指标。与IoU只关注重叠区域不同,GIoU不仅关注重叠区域,还关注其他的非重合区域,能更好的反映两者的重合度。
缺陷
状态1、2、3都是预测框在目标框内部且预测框大小一致的情况,这时预测框和目标框的差集都是相同的,因此这三种状态的GIOU值也都是相同的,这时GIOU退化成了IOU,无法区分相对位置关系。
DIoU
基于GIoU的问题,2020年的AAAI又提出了DIoU的概念。
概念
一个好的目标框回归函数应该考虑三个重要几何因素:**重叠面积、中心点距离,长宽比。**针对IOU和GIOU存在的问题,作者提出了两个问题:
- 如何最小化预测框和目标框之间的归一化距离?
- 如何在预测框和目标框重叠时,回归的更准确?
针对第一个问题,作者提出了DIoU: D I o U = I o U − ρ 2 ( b , b g t ) c 2 DIoU=IoU-\frac{ρ^{2}(b, b^{gt})}{c^{2}} DIoU=IoU−c2ρ2(b,bgt),惩罚项为 R D I o U = ρ 2 ( b , b g t ) c 2 R_{DIoU}=\frac{ρ^{2}(b, b^{gt})}{c^{2}} RDIoU=c2ρ2(b,bgt),其中 b b b和 b g t b^{gt} bgt分别表示预测框B和预测框Bgt的中心点, ρ ( ⋅ ) ρ(·) ρ(⋅)表示欧式距离,c表示预测框B和预测框Bgt的最小外接矩形的对角线距离。
DIoU要比GIou更加符合目标框回归的机制,它将目标与anchor之间的距离,重叠率以及尺度都考虑进去,这使得目标框回归变得更加稳定,不会像IoU和GIoU一样出现训练过程中发散等问题。
DIOU_Loss考虑了重叠面积和中心点距离,当目标框包裹预测框的时候,直接度量2个框的距离,因此DIOU_Loss收敛的更快。
Code
def distance(point1, point2):
"""
计算两点间的欧氏距离,point 的坐标形式为 xy
"""
x1, y1 = point1
x2, y2 = point2
return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
def DIoU(box1, box2):
"""
计算两个 box 的 DIoU,box 的坐标形式为 xyxy
"""
area1 = area(box1)
area2 = area(box2)
sumArea = area1 + area2
xa1, ya1, xa2, ya2 = box1
xb1, yb1, xb2, yb2 = box2
centerx1, centery1 = (xa1 + xa2) / 2, (ya1 + ya2) / 2
centerx2, centery2 = (xb1 + xb2) / 2, (yb1 + yb2) / 2
outerx1, outery1 = min(xa1, xb1), min(ya1, yb1)
outerx2, outery2 = max(xa2, xb2), max(ya2, yb2)
p = distance([centerx1, centery1], [centerx2, centery2])
c = distance([outerx1, outery1], [outerx2, outery2])
iou = IoU(box1, box2)
return iou - p ** 2 / c ** 2
缺陷
没有考虑长宽比。
CIoU
概念
DIoU并没有考虑到长宽比的因素,因此作者进一步在DIoU的基础上提出了CIoU: C I o U = I o U − ρ 2 ( b , b g t ) c 2 − α v CIoU=I o U-\frac{\rho^{2}\left(\mathbf{b}, \mathbf{b}^{g t}\right)}{c^{2}}-\alpha v CIoU=IoU−c2ρ2(b,bgt)−αv,惩罚项为: R C I O U = ρ 2 ( b , b g t ) c 2 + α v R_{C I O U}=\frac{\rho^{2}\left(b, b^{g t}\right)}{c^{2}}+\alpha v RCIOU=c2ρ2(b,bgt)+αv,其中 v = 4 π 2 ( arctan w g t h g t − arctan w h ) 2 v=\frac{4}{\pi^{2}}\left(\arctan \frac{w^{g t}}{h^{g t}}-\arctan \frac{w}{h}\right)^{2} v=π24(arctanhgtwgt−arctanhw)2, α = v ( 1 − I o U ) + v \alpha=\frac{v}{(1-I o U)+v} α=(1−IoU)+vv,v是用来度量长宽比的相似性。
Code
def CIoU(box1, box2):
"""
计算两个 box 的 CIoU,box 的坐标形式为 xyxy
"""
area1 = area(box1)
area2 = area(box2)
sumArea = area1 + area2
xa1, ya1, xa2, ya2 = box1
xb1, yb1, xb2, yb2 = box2
centerx1, centery1 = (xa1 + xa2) / 2, (ya1 + ya2) / 2
centerx2, centery2 = (xb1 + xb2) / 2, (yb1 + yb2) / 2
outerx1, outery1 = min(xa1, xb1), min(ya1, yb1)
outerx2, outery2 = max(xa2, xb2), max(ya2, yb2)
p = distance([centerx1, centery1], [centerx2, centery2])
c = distance([outerx1, outery1], [outerx2, outery2])
w, h, wg, hg = abs(xa2 - xa1), abs(ya2 - ya1), abs(xb2 - xb1), abs(yb2 - yb1)
v = 4 / math.pi ** 2 * (math.atan(w / h) - math.atan(wg / hg)) ** 2
iou = IoU(box1, box2)
alpha = v / ((1 - iou) + v)
return iou - p ** 2 / c ** 2 - alpha * v
总结
**IOU:**主要考虑检测框和目标框重叠面积。
**GIOU:**在IOU的基础上,解决边界框不重合时的问题。
**DIOU:**在IOU和GIOU的基础上,考虑边界框中心点距离的信息。
**CIOU:**在DIOU的基础上,考虑边界框宽高比的尺度信息。
参考链接:
- IoU、GIoU、DIoU、CIoU损失函数的那点事儿
- AAAI 2020 | DIoU 和 CIoU:IoU 在目标检测中的正确打开方式
- 深入浅出Yolo系列之Yolov3&Yolov4&Yolov5核心基础知识完整讲解