D I O U DIOU DIOU
diou = IOU - d^2/c^2
d^2:表示预测框和真实框中心点之间的距离distance1
c^2:表示包裹两个框的最小框的左上角和右下角距离distance2
distance1越小,distance2越大,diou越大,一定程度就是两个框接近且重合度高
LDiou = 1-diou,loss越小越好,所以diou越大越好
所以就是要distance1越小,distance2越大
所以在真实框固定的情况下,需要预测框中心点向真实框中心点靠近(distance1越小)
假设预测框中心点向真实框中心点靠近发生了,如果要(distance2越大)只能扩大预测的宽高,即范围,这样的话是符合要求的。
但是distance1的变大,也会导致distance2变大,这里不就矛盾了吗?
DIoU的优点如下:
1.与GIoU loss类似,DIoU loss在与目标框不重叠时,仍然可以为边界框提供移动方向。
2.DIoU loss可以直接最小化两个目标框的距离,而GIOU loss优化的是两个目标框之间的面积,因此比GIoU loss收敛快得多。
3.对于包含两个框在水平方向和垂直方向上这种情况,DIoU损失可以使回归非常快,而GIoU损失几乎退化为IoU损失
Distance-IoU(DIoU) loss
Loss(diou) = 1 - IOU - d^2/c^2
def bboxes_diou(boxes1,boxes2):
'''
cal DIOU of two boxes or batch boxes
:param boxes1:[xmin,ymin,xmax,ymax] or
[[xmin,ymin,xmax,ymax],[xmin,ymin,xmax,ymax],...]
:param boxes2:[xmin,ymin,xmax,ymax]
:return:
'''
#cal the box's area of boxes1 and boxess
boxes1Area = (boxes1[...,2]-boxes1[...,0])*(boxes1[...,3]-boxes1[...,1])
boxes2Area = (boxes2[..., 2] - boxes2[..., 0]) * (boxes2[..., 3] - boxes2[..., 1])
#cal Intersection
left_up = np.maximum(boxes1[...,:2],boxes2[...,:2])
right_down = np.minimum(boxes1[...,2:],boxes2[...,2:])
inter_section = np.maximum(right_down-left_up,0.0)
inter_area = inter_section[...,0] * inter_section[...,1]
union_area = boxes1Area+boxes2Area-inter_area
ious = np.maximum(1.0*inter_area/union_area,np.finfo(np.float32).eps)
#cal outer boxes
outer_left_up = np.minimum(boxes1[..., :2], boxes2[..., :2])
outer_right_down = np.maximum(boxes1[..., 2:], boxes2[..., 2:])
outer = np.maximum(outer_right_down - outer_left_up, 0.0)
outer_diagonal_line = np.square(outer[...,0]) + np.square(outer[...,1])
#cal center distance
boxes1_center = (boxes1[..., :2] + boxes1[...,2:]) * 0.5
boxes2_center = (boxes2[..., :2] + boxes2[...,2:]) * 0.5
center_dis = np.square(boxes1_center[...,0]-boxes2_center[...,0]) +\
np.square(boxes1_center[...,1]-boxes2_center[...,1])
#cal diou
dious = ious - center_dis / outer_diagonal_line
return dious
- IoU:从IoU误差的曲线我们可以发现,anchor越靠近边缘,误差越大,那些与目标框没有重叠的anchor基本无法回归。
- GIoU:从GIoU误差的曲线我们可以发现,对于一些没有重叠的anchor,GIoU的表现要比IoU更好。但是由于GIoU仍然严重的依赖IoU,因此在两个垂直方向,误差很大,基本很难收敛,这就是GIoU不稳定的原因。
- DIoU:从DIoU误差的曲线我们可以发现,对于不同距离,方向,面积和比例的anchor,DIoU都能做到较好的回归