1. x c y c w h x_cy_cwh xcycwh <=> x 1 y 1 x 2 y 2 x_1y_1x_2y_2 x1y1x2y2
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)
def box_xyxy_to_cxcywh(x):
x0, y0, x1, y1 = x.unbind(-1)
b = [(x0 + x1) / 2, (y0 + y1) / 2,
(x1 - x0), (y1 - y0)]
return paddle.stack(b, axis=-1)
输入 x
shape 为 [num, 4]
2. 计算 x 1 y 1 x 2 y 2 x_1y_1x_2y_2 x1y1x2y2 box的面积
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]
3. 计算 x 1 y 1 x 2 y 2 x_1y_1x_2y_2 x1y1x2y2 box 的 IoU
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]
4. 计算 x 1 y 1 x 2 y 2 x_1y_1x_2y_2 x1y1x2y2 box 的 GIoU
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