def box_cxcywh_to_xyxy(x):
x_c, y_c, w, h = x.unbind(-1)
b = [(x_c - 0.5 * w), (y_c - 0.5 * h),
(x_c + 0.5 * w), (y_c + 0.5 * h)]
return paddle.stack(b, axis=-1)
输入 x
shape 为 [num, 4]
def box_area(boxes: paddle.Tensor) -> paddle.Tensor:
"""
Computes the area of a set of bounding boxes, which are specified by their
(x1, y1, x2, y2) coordinates.
Args:
boxes (Tensor[N, 4]): boxes for which the area will be computed. They
are expected to be in (x1, y1, x2, y2) format with
``0 <= x1 < x2`` and ``0 <= y1 < y2``.
Returns:
Tensor[N]: the area for each box
"""
# boxes = _upcast(boxes)
return (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])
输入 x
shape 为 [num, 4]
def box_iou(boxes1, boxes2):
area1 = box_area(boxes1)
area2 = box_area(boxes2)
lt = paddle.maximum(boxes1[:, None, :2], boxes2[:, :2]) # [N,M,2]
rb = paddle.minimum(boxes1[:, None, 2:], boxes2[:, 2:]) # [N,M,2]
wh = (rb - lt).clip(min=0) # [N,M,2]
inter = wh[:, :, 0] * wh[:, :, 1] # [N,M]
union = area1[:, None] + area2 - inter
iou = inter / union
return iou, union
输入 boxes1
shape 为 [num1, 4]
输入 boxes2
shape 为 [num2, 4]
iou
shape 为 [num1, num2]
def generalized_box_iou(boxes1, boxes2):
"""
Generalized IoU from https://giou.stanford.edu/
The boxes should be in [x0, y0, x1, y1] format
Returns a [N, M] pairwise matrix, where N = len(boxes1)
and M = len(boxes2)
"""
# degenerate boxes gives inf / nan results
# so do an early check
assert (boxes1[:, 2:] >= boxes1[:, :2]).all()
assert (boxes2[:, 2:] >= boxes2[:, :2]).all()
iou, union = box_iou(boxes1, boxes2)
lt = paddle.minimum(boxes1[:, None, :2], boxes2[:, :2])
rb = paddle.maximum(boxes1[:, None, 2:], boxes2[:, 2:])
wh = (rb - lt).clip(min=0) # [N,M,2]
area = wh[:, :, 0] * wh[:, :, 1] # 总面积
return iou - (area - union) / area