|
"""
|
|
Copied from RT-DETR (https://github.com/lyuwenyu/RT-DETR)
|
|
Copyright(c) 2023 lyuwenyu. All Rights Reserved.
|
|
"""
|
|
|
|
from enum import Enum
|
|
|
|
import torch
|
|
import torchvision
|
|
from torch import Tensor
|
|
|
|
|
|
class BoxProcessFormat(Enum):
|
|
"""Box process format
|
|
|
|
Available formats are
|
|
* ``RESIZE``
|
|
* ``RESIZE_KEEP_RATIO``
|
|
* ``RESIZE_KEEP_RATIO_PADDING``
|
|
"""
|
|
|
|
RESIZE = 1
|
|
RESIZE_KEEP_RATIO = 2
|
|
RESIZE_KEEP_RATIO_PADDING = 3
|
|
|
|
|
|
def box_revert(
|
|
boxes: Tensor,
|
|
orig_sizes: Tensor = None,
|
|
eval_sizes: Tensor = None,
|
|
inpt_sizes: Tensor = None,
|
|
inpt_padding: Tensor = None,
|
|
normalized: bool = True,
|
|
in_fmt: str = "cxcywh",
|
|
out_fmt: str = "xyxy",
|
|
process_fmt=BoxProcessFormat.RESIZE,
|
|
) -> Tensor:
|
|
"""
|
|
Args:
|
|
boxes(Tensor), [N, :, 4], (x1, y1, x2, y2), pred boxes.
|
|
inpt_sizes(Tensor), [N, 2], (w, h). input sizes.
|
|
orig_sizes(Tensor), [N, 2], (w, h). origin sizes.
|
|
inpt_padding (Tensor), [N, 2], (w_pad, h_pad, ...).
|
|
(inpt_sizes + inpt_padding) == eval_sizes
|
|
"""
|
|
assert in_fmt in ("cxcywh", "xyxy"), ""
|
|
|
|
if normalized and eval_sizes is not None:
|
|
boxes = boxes * eval_sizes.repeat(1, 2).unsqueeze(1)
|
|
|
|
if inpt_padding is not None:
|
|
if in_fmt == "xyxy":
|
|
boxes -= inpt_padding[:, :2].repeat(1, 2).unsqueeze(1)
|
|
elif in_fmt == "cxcywh":
|
|
boxes[..., :2] -= inpt_padding[:, :2].repeat(1, 2).unsqueeze(1)
|
|
|
|
if orig_sizes is not None:
|
|
orig_sizes = orig_sizes.repeat(1, 2).unsqueeze(1)
|
|
if inpt_sizes is not None:
|
|
inpt_sizes = inpt_sizes.repeat(1, 2).unsqueeze(1)
|
|
boxes = boxes * (orig_sizes / inpt_sizes)
|
|
else:
|
|
boxes = boxes * orig_sizes
|
|
|
|
boxes = torchvision.ops.box_convert(boxes, in_fmt=in_fmt, out_fmt=out_fmt)
|
|
return boxes
|
|
|