|
|
|
from typing import Optional, Sequence, Union |
|
|
|
from torch import Tensor |
|
|
|
from mmdet.registry import TASK_UTILS |
|
from mmdet.structures.bbox import (BaseBoxes, HorizontalBoxes, bbox2distance, |
|
distance2bbox, get_box_tensor) |
|
from .base_bbox_coder import BaseBBoxCoder |
|
|
|
|
|
@TASK_UTILS.register_module() |
|
class DistancePointBBoxCoder(BaseBBoxCoder): |
|
"""Distance Point BBox coder. |
|
|
|
This coder encodes gt bboxes (x1, y1, x2, y2) into (top, bottom, left, |
|
right) and decode it back to the original. |
|
|
|
Args: |
|
clip_border (bool, optional): Whether clip the objects outside the |
|
border of the image. Defaults to True. |
|
""" |
|
|
|
def __init__(self, clip_border: Optional[bool] = True, **kwargs) -> None: |
|
super().__init__(**kwargs) |
|
self.clip_border = clip_border |
|
|
|
def encode(self, |
|
points: Tensor, |
|
gt_bboxes: Union[Tensor, BaseBoxes], |
|
max_dis: Optional[float] = None, |
|
eps: float = 0.1) -> Tensor: |
|
"""Encode bounding box to distances. |
|
|
|
Args: |
|
points (Tensor): Shape (N, 2), The format is [x, y]. |
|
gt_bboxes (Tensor or :obj:`BaseBoxes`): Shape (N, 4), The format |
|
is "xyxy" |
|
max_dis (float): Upper bound of the distance. Default None. |
|
eps (float): a small value to ensure target < max_dis, instead <=. |
|
Default 0.1. |
|
|
|
Returns: |
|
Tensor: Box transformation deltas. The shape is (N, 4). |
|
""" |
|
gt_bboxes = get_box_tensor(gt_bboxes) |
|
assert points.size(0) == gt_bboxes.size(0) |
|
assert points.size(-1) == 2 |
|
assert gt_bboxes.size(-1) == 4 |
|
return bbox2distance(points, gt_bboxes, max_dis, eps) |
|
|
|
def decode( |
|
self, |
|
points: Tensor, |
|
pred_bboxes: Tensor, |
|
max_shape: Optional[Union[Sequence[int], Tensor, |
|
Sequence[Sequence[int]]]] = None |
|
) -> Union[Tensor, BaseBoxes]: |
|
"""Decode distance prediction to bounding box. |
|
|
|
Args: |
|
points (Tensor): Shape (B, N, 2) or (N, 2). |
|
pred_bboxes (Tensor): Distance from the given point to 4 |
|
boundaries (left, top, right, bottom). Shape (B, N, 4) |
|
or (N, 4) |
|
max_shape (Sequence[int] or torch.Tensor or Sequence[ |
|
Sequence[int]],optional): Maximum bounds for boxes, specifies |
|
(H, W, C) or (H, W). If priors shape is (B, N, 4), then |
|
the max_shape should be a Sequence[Sequence[int]], |
|
and the length of max_shape should also be B. |
|
Default None. |
|
Returns: |
|
Union[Tensor, :obj:`BaseBoxes`]: Boxes with shape (N, 4) or |
|
(B, N, 4) |
|
""" |
|
assert points.size(0) == pred_bboxes.size(0) |
|
assert points.size(-1) == 2 |
|
assert pred_bboxes.size(-1) == 4 |
|
if self.clip_border is False: |
|
max_shape = None |
|
bboxes = distance2bbox(points, pred_bboxes, max_shape) |
|
|
|
if self.use_box_type: |
|
bboxes = HorizontalBoxes(bboxes) |
|
return bboxes |
|
|