Unverified Commit b5a706d4 authored by Quantum Cat's avatar Quantum Cat Committed by GitHub
Browse files

[Feature] Add type hint for code in `models/task_modules` (#2485)



* 2023/04/28 add task_modules type hint

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/coders/groupfree3d_bbox_coder.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* Update mmdet3d/models/task_modules/anchor/anchor_3d_generator.py
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>

* 2023/05/19 fix_wrong_hint

* Update centerpoint_bbox_coders.py

* Update iou_neg_piecewise_sampler.py

---------
Co-authored-by: default avatarXiang Xu <xuxiang0103@gmail.com>
parent 5734aef8
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import List, Tuple, Union
import mmengine import mmengine
import torch import torch
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
...@@ -37,13 +40,13 @@ class Anchor3DRangeGenerator(object): ...@@ -37,13 +40,13 @@ class Anchor3DRangeGenerator(object):
""" """
def __init__(self, def __init__(self,
ranges, ranges: List[List[float]],
sizes=[[3.9, 1.6, 1.56]], sizes: List[List[float]] = [[3.9, 1.6, 1.56]],
scales=[1], scales: List[int] = [1],
rotations=[0, 1.5707963], rotations: List[float] = [0, 1.5707963],
custom_values=(), custom_values: Tuple[float] = (),
reshape_out=True, reshape_out: bool = True,
size_per_range=True): size_per_range: bool = True) -> None:
assert mmengine.is_list_of(ranges, list) assert mmengine.is_list_of(ranges, list)
if size_per_range: if size_per_range:
if len(sizes) != len(ranges): if len(sizes) != len(ranges):
...@@ -64,7 +67,7 @@ class Anchor3DRangeGenerator(object): ...@@ -64,7 +67,7 @@ class Anchor3DRangeGenerator(object):
self.reshape_out = reshape_out self.reshape_out = reshape_out
self.size_per_range = size_per_range self.size_per_range = size_per_range
def __repr__(self): def __repr__(self) -> str:
s = self.__class__.__name__ + '(' s = self.__class__.__name__ + '('
s += f'anchor_range={self.ranges},\n' s += f'anchor_range={self.ranges},\n'
s += f'scales={self.scales},\n' s += f'scales={self.scales},\n'
...@@ -75,18 +78,21 @@ class Anchor3DRangeGenerator(object): ...@@ -75,18 +78,21 @@ class Anchor3DRangeGenerator(object):
return s return s
@property @property
def num_base_anchors(self): def num_base_anchors(self) -> int:
"""list[int]: Total number of base anchors in a feature grid.""" """int: Total number of base anchors in a feature grid."""
num_rot = len(self.rotations) num_rot = len(self.rotations)
num_size = torch.tensor(self.sizes).reshape(-1, 3).size(0) num_size = torch.tensor(self.sizes).reshape(-1, 3).size(0)
return num_rot * num_size return num_rot * num_size
@property @property
def num_levels(self): def num_levels(self) -> int:
"""int: Number of feature levels that the generator is applied to.""" """int: Number of feature levels that the generator is applied to."""
return len(self.scales) return len(self.scales)
def grid_anchors(self, featmap_sizes, device='cuda'): def grid_anchors(
self,
featmap_sizes: List[Tuple[int]],
device: Union[str, torch.device] = 'cuda') -> List[Tensor]:
"""Generate grid anchors in multiple feature levels. """Generate grid anchors in multiple feature levels.
Args: Args:
...@@ -112,7 +118,11 @@ class Anchor3DRangeGenerator(object): ...@@ -112,7 +118,11 @@ class Anchor3DRangeGenerator(object):
multi_level_anchors.append(anchors) multi_level_anchors.append(anchors)
return multi_level_anchors return multi_level_anchors
def single_level_grid_anchors(self, featmap_size, scale, device='cuda'): def single_level_grid_anchors(
self,
featmap_size: Tuple[int],
scale: int,
device: Union[str, torch.device] = 'cuda') -> Tensor:
"""Generate grid anchors of a single level feature map. """Generate grid anchors of a single level feature map.
This function is usually called by method ``self.grid_anchors``. This function is usually called by method ``self.grid_anchors``.
...@@ -152,13 +162,14 @@ class Anchor3DRangeGenerator(object): ...@@ -152,13 +162,14 @@ class Anchor3DRangeGenerator(object):
mr_anchors = torch.cat(mr_anchors, dim=-3) mr_anchors = torch.cat(mr_anchors, dim=-3)
return mr_anchors return mr_anchors
def anchors_single_range(self, def anchors_single_range(
feature_size, self,
anchor_range, feature_size: Tuple[int],
scale=1, anchor_range: Union[Tensor, List[float]],
sizes=[[3.9, 1.6, 1.56]], scale: int = 1,
rotations=[0, 1.5707963], sizes: Union[List[List[float]], List[float]] = [[3.9, 1.6, 1.56]],
device='cuda'): rotations: List[float] = [0, 1.5707963],
device: Union[str, torch.device] = 'cuda') -> Tensor:
"""Generate anchors in a single range. """Generate anchors in a single range.
Args: Args:
...@@ -248,17 +259,18 @@ class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator): ...@@ -248,17 +259,18 @@ class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator):
center of the corresponding greature grid. Defaults to False. center of the corresponding greature grid. Defaults to False.
""" """
def __init__(self, align_corner=False, **kwargs): def __init__(self, align_corner: bool = False, **kwargs) -> None:
super(AlignedAnchor3DRangeGenerator, self).__init__(**kwargs) super(AlignedAnchor3DRangeGenerator, self).__init__(**kwargs)
self.align_corner = align_corner self.align_corner = align_corner
def anchors_single_range(self, def anchors_single_range(
feature_size, self,
anchor_range, feature_size: List[int],
scale, anchor_range: List[float],
sizes=[[3.9, 1.6, 1.56]], scale: int,
rotations=[0, 1.5707963], sizes: Union[List[List[float]], List[float]] = [[3.9, 1.6, 1.56]],
device='cuda'): rotations: List[float] = [0, 1.5707963],
device: Union[str, torch.device] = 'cuda') -> Tensor:
"""Generate anchors in a single range. """Generate anchors in a single range.
Args: Args:
...@@ -352,12 +364,15 @@ class AlignedAnchor3DRangeGeneratorPerCls(AlignedAnchor3DRangeGenerator): ...@@ -352,12 +364,15 @@ class AlignedAnchor3DRangeGeneratorPerCls(AlignedAnchor3DRangeGenerator):
:class:`AlignedAnchor3DRangeGenerator`. :class:`AlignedAnchor3DRangeGenerator`.
""" """
def __init__(self, **kwargs): def __init__(self, **kwargs) -> None:
super(AlignedAnchor3DRangeGeneratorPerCls, self).__init__(**kwargs) super(AlignedAnchor3DRangeGeneratorPerCls, self).__init__(**kwargs)
assert len(self.scales) == 1, 'Multi-scale feature map levels are' + \ assert len(self.scales) == 1, 'Multi-scale feature map levels are' + \
' not supported currently in this kind of anchor generator.' ' not supported currently in this kind of anchor generator.'
def grid_anchors(self, featmap_sizes, device='cuda'): def grid_anchors(
self,
featmap_sizes: List[Tuple[int]],
device: Union[str, torch.device] = 'cuda') -> List[List[Tensor]]:
"""Generate grid anchors in multiple feature levels. """Generate grid anchors in multiple feature levels.
Args: Args:
...@@ -379,7 +394,11 @@ class AlignedAnchor3DRangeGeneratorPerCls(AlignedAnchor3DRangeGenerator): ...@@ -379,7 +394,11 @@ class AlignedAnchor3DRangeGeneratorPerCls(AlignedAnchor3DRangeGenerator):
multi_level_anchors.append(anchors) multi_level_anchors.append(anchors)
return multi_level_anchors return multi_level_anchors
def multi_cls_grid_anchors(self, featmap_sizes, scale, device='cuda'): def multi_cls_grid_anchors(
self,
featmap_sizes: List[Tuple[int]],
scale: int,
device: Union[str, torch.device] = 'cuda') -> List[Tensor]:
"""Generate grid anchors of a single level feature map for multi-class """Generate grid anchors of a single level feature map for multi-class
with different feature map sizes. with different feature map sizes.
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import warnings import warnings
from typing import Any
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from mmdet3d.utils import ConfigType
PRIOR_GENERATORS = TASK_UTILS PRIOR_GENERATORS = TASK_UTILS
ANCHOR_GENERATORS = TASK_UTILS ANCHOR_GENERATORS = TASK_UTILS
def build_prior_generator(cfg, default_args=None): def build_prior_generator(cfg: ConfigType, default_args=None) -> Any:
warnings.warn( warnings.warn(
'``build_prior_generator`` would be deprecated soon, please use ' '``build_prior_generator`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ') '``mmdet3d.registry.TASK_UTILS.build()`` ')
return TASK_UTILS.build(cfg, default_args=default_args) return TASK_UTILS.build(cfg, default_args=default_args)
def build_anchor_generator(cfg, default_args=None): def build_anchor_generator(cfg: ConfigType, default_args=None) -> Any:
warnings.warn( warnings.warn(
'``build_anchor_generator`` would be deprecated soon, please use ' '``build_anchor_generator`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ') '``mmdet3d.registry.TASK_UTILS.build()`` ')
......
...@@ -42,7 +42,8 @@ class Max3DIoUAssigner(MaxIoUAssigner): ...@@ -42,7 +42,8 @@ class Max3DIoUAssigner(MaxIoUAssigner):
iou_calculator (dict): Config of overlaps Calculator. iou_calculator (dict): Config of overlaps Calculator.
""" """
def __init__(self, def __init__(
self,
pos_iou_thr: float, pos_iou_thr: float,
neg_iou_thr: Union[float, tuple], neg_iou_thr: Union[float, tuple],
min_pos_iou: float = .0, min_pos_iou: float = .0,
...@@ -51,7 +52,8 @@ class Max3DIoUAssigner(MaxIoUAssigner): ...@@ -51,7 +52,8 @@ class Max3DIoUAssigner(MaxIoUAssigner):
ignore_wrt_candidates: bool = True, ignore_wrt_candidates: bool = True,
match_low_quality: bool = True, match_low_quality: bool = True,
gpu_assign_thr: float = -1, gpu_assign_thr: float = -1,
iou_calculator: dict = dict(type='BboxOverlaps2D')): iou_calculator: dict = dict(type='BboxOverlaps2D')
) -> None:
self.pos_iou_thr = pos_iou_thr self.pos_iou_thr = pos_iou_thr
self.neg_iou_thr = neg_iou_thr self.neg_iou_thr = neg_iou_thr
self.min_pos_iou = min_pos_iou self.min_pos_iou = min_pos_iou
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import warnings import warnings
from typing import Any
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from mmdet3d.utils.typing_utils import ConfigType
BBOX_ASSIGNERS = TASK_UTILS BBOX_ASSIGNERS = TASK_UTILS
BBOX_SAMPLERS = TASK_UTILS BBOX_SAMPLERS = TASK_UTILS
BBOX_CODERS = TASK_UTILS BBOX_CODERS = TASK_UTILS
def build_assigner(cfg, **default_args): def build_assigner(cfg: ConfigType, **default_args) -> Any:
"""Builder of box assigner.""" """Builder of box assigner."""
warnings.warn('``build_assigner`` would be deprecated soon, please use ' warnings.warn('``build_assigner`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ') '``mmdet3d.registry.TASK_UTILS.build()`` ')
return TASK_UTILS.build(cfg, default_args=default_args) return TASK_UTILS.build(cfg, default_args=default_args)
def build_sampler(cfg, **default_args): def build_sampler(cfg: ConfigType, **default_args) -> Any:
"""Builder of box sampler.""" """Builder of box sampler."""
warnings.warn('``build_sampler`` would be deprecated soon, please use ' warnings.warn('``build_sampler`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ') '``mmdet3d.registry.TASK_UTILS.build()`` ')
return TASK_UTILS.build(cfg, default_args=default_args) return TASK_UTILS.build(cfg, default_args=default_args)
def build_bbox_coder(cfg, **default_args): def build_bbox_coder(cfg: ConfigType, **default_args) -> Any:
"""Builder of box coder.""" """Builder of box coder."""
warnings.warn('``build_bbox_coder`` would be deprecated soon, please use ' warnings.warn('``build_bbox_coder`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ') '``mmdet3d.registry.TASK_UTILS.build()`` ')
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import Dict
import numpy as np import numpy as np
import torch import torch
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from mmdet3d.structures import BaseInstance3DBoxes
from .partial_bin_based_bbox_coder import PartialBinBasedBBoxCoder from .partial_bin_based_bbox_coder import PartialBinBasedBBoxCoder
...@@ -15,13 +19,14 @@ class AnchorFreeBBoxCoder(PartialBinBasedBBoxCoder): ...@@ -15,13 +19,14 @@ class AnchorFreeBBoxCoder(PartialBinBasedBBoxCoder):
with_rot (bool): Whether the bbox is with rotation. with_rot (bool): Whether the bbox is with rotation.
""" """
def __init__(self, num_dir_bins, with_rot=True): def __init__(self, num_dir_bins: int, with_rot: bool = True) -> None:
super(AnchorFreeBBoxCoder, self).__init__( super(AnchorFreeBBoxCoder, self).__init__(
num_dir_bins, 0, [], with_rot=with_rot) num_dir_bins, 0, [], with_rot=with_rot)
self.num_dir_bins = num_dir_bins self.num_dir_bins = num_dir_bins
self.with_rot = with_rot self.with_rot = with_rot
def encode(self, gt_bboxes_3d, gt_labels_3d): def encode(self, gt_bboxes_3d: BaseInstance3DBoxes,
gt_labels_3d: Tensor) -> tuple:
"""Encode ground truth to prediction targets. """Encode ground truth to prediction targets.
Args: Args:
...@@ -51,7 +56,7 @@ class AnchorFreeBBoxCoder(PartialBinBasedBBoxCoder): ...@@ -51,7 +56,7 @@ class AnchorFreeBBoxCoder(PartialBinBasedBBoxCoder):
return (center_target, size_res_target, dir_class_target, return (center_target, size_res_target, dir_class_target,
dir_res_target) dir_res_target)
def decode(self, bbox_out): def decode(self, bbox_out: dict) -> Tensor:
"""Decode predicted parts to bbox3d. """Decode predicted parts to bbox3d.
Args: Args:
...@@ -85,7 +90,8 @@ class AnchorFreeBBoxCoder(PartialBinBasedBBoxCoder): ...@@ -85,7 +90,8 @@ class AnchorFreeBBoxCoder(PartialBinBasedBBoxCoder):
bbox3d = torch.cat([center, bbox_size, dir_angle], dim=-1) bbox3d = torch.cat([center, bbox_size, dir_angle], dim=-1)
return bbox3d return bbox3d
def split_pred(self, cls_preds, reg_preds, base_xyz): def split_pred(self, cls_preds: Tensor, reg_preds: Tensor,
base_xyz: Tensor) -> Dict[str, Tensor]:
"""Split predicted features to specific parts. """Split predicted features to specific parts.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import Dict, List, Optional, Tuple
import torch import torch
from mmdet.models.task_modules import BaseBBoxCoder from mmdet.models.task_modules import BaseBBoxCoder
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
...@@ -22,13 +25,13 @@ class CenterPointBBoxCoder(BaseBBoxCoder): ...@@ -22,13 +25,13 @@ class CenterPointBBoxCoder(BaseBBoxCoder):
""" """
def __init__(self, def __init__(self,
pc_range, pc_range: List[float],
out_size_factor, out_size_factor: int,
voxel_size, voxel_size: List[float],
post_center_range=None, post_center_range: Optional[List[float]] = None,
max_num=100, max_num: int = 100,
score_threshold=None, score_threshold: Optional[float] = None,
code_size=9): code_size: int = 9) -> None:
self.pc_range = pc_range self.pc_range = pc_range
self.out_size_factor = out_size_factor self.out_size_factor = out_size_factor
...@@ -38,7 +41,10 @@ class CenterPointBBoxCoder(BaseBBoxCoder): ...@@ -38,7 +41,10 @@ class CenterPointBBoxCoder(BaseBBoxCoder):
self.score_threshold = score_threshold self.score_threshold = score_threshold
self.code_size = code_size self.code_size = code_size
def _gather_feat(self, feats, inds, feat_masks=None): def _gather_feat(self,
feats: Tensor,
inds: Tensor,
feat_masks: Optional[Tensor] = None) -> Tensor:
"""Given feats and indexes, returns the gathered feats. """Given feats and indexes, returns the gathered feats.
Args: Args:
...@@ -60,7 +66,7 @@ class CenterPointBBoxCoder(BaseBBoxCoder): ...@@ -60,7 +66,7 @@ class CenterPointBBoxCoder(BaseBBoxCoder):
feats = feats.view(-1, dim) feats = feats.view(-1, dim)
return feats return feats
def _topk(self, scores, K=80): def _topk(self, scores: Tensor, K: int = 80) -> Tuple[Tensor]:
"""Get indexes based on scores. """Get indexes based on scores.
Args: Args:
...@@ -95,7 +101,7 @@ class CenterPointBBoxCoder(BaseBBoxCoder): ...@@ -95,7 +101,7 @@ class CenterPointBBoxCoder(BaseBBoxCoder):
return topk_score, topk_inds, topk_clses, topk_ys, topk_xs return topk_score, topk_inds, topk_clses, topk_ys, topk_xs
def _transpose_and_gather_feat(self, feat, ind): def _transpose_and_gather_feat(self, feat: Tensor, ind: Tensor) -> Tensor:
"""Given feats and indexes, returns the transposed and gathered feats. """Given feats and indexes, returns the transposed and gathered feats.
Args: Args:
...@@ -115,14 +121,14 @@ class CenterPointBBoxCoder(BaseBBoxCoder): ...@@ -115,14 +121,14 @@ class CenterPointBBoxCoder(BaseBBoxCoder):
pass pass
def decode(self, def decode(self,
heat, heat: Tensor,
rot_sine, rot_sine: Tensor,
rot_cosine, rot_cosine: Tensor,
hei, hei: Tensor,
dim, dim: Tensor,
vel, vel: Tensor,
reg=None, reg: Optional[Tensor] = None,
task_id=-1): task_id: int = -1) -> List[Dict[str, Tensor]]:
"""Decode bboxes. """Decode bboxes.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import torch import torch
from mmdet.models.task_modules import BaseBBoxCoder from mmdet.models.task_modules import BaseBBoxCoder
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
...@@ -13,12 +14,12 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder): ...@@ -13,12 +14,12 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder):
code_size (int): The dimension of boxes to be encoded. code_size (int): The dimension of boxes to be encoded.
""" """
def __init__(self, code_size=7): def __init__(self, code_size: int = 7) -> None:
super(DeltaXYZWLHRBBoxCoder, self).__init__() super(DeltaXYZWLHRBBoxCoder, self).__init__()
self.code_size = code_size self.code_size = code_size
@staticmethod @staticmethod
def encode(src_boxes, dst_boxes): def encode(src_boxes: Tensor, dst_boxes: Tensor) -> Tensor:
"""Get box regression transformation deltas (dx, dy, dz, dx_size, """Get box regression transformation deltas (dx, dy, dz, dx_size,
dy_size, dz_size, dr, dv*) that can be used to transform the dy_size, dz_size, dr, dv*) that can be used to transform the
`src_boxes` into the `target_boxes`. `src_boxes` into the `target_boxes`.
...@@ -55,7 +56,7 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder): ...@@ -55,7 +56,7 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder):
return torch.cat([xt, yt, zt, wt, lt, ht, rt, *cts], dim=-1) return torch.cat([xt, yt, zt, wt, lt, ht, rt, *cts], dim=-1)
@staticmethod @staticmethod
def decode(anchors, deltas): def decode(anchors: Tensor, deltas: Tensor) -> Tensor:
"""Apply transformation `deltas` (dx, dy, dz, dx_size, dy_size, """Apply transformation `deltas` (dx, dy, dz, dx_size, dy_size,
dz_size, dr, dv*) to `boxes`. dz_size, dr, dv*) to `boxes`.
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import Optional, Tuple
import numpy as np import numpy as np
import torch import torch
from mmdet.models.task_modules import BaseBBoxCoder from mmdet.models.task_modules import BaseBBoxCoder
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from mmdet3d.structures.bbox_3d import limit_period from mmdet3d.structures.bbox_3d import limit_period
...@@ -22,10 +25,10 @@ class FCOS3DBBoxCoder(BaseBBoxCoder): ...@@ -22,10 +25,10 @@ class FCOS3DBBoxCoder(BaseBBoxCoder):
""" """
def __init__(self, def __init__(self,
base_depths=None, base_depths: Optional[Tuple[Tuple[float]]] = None,
base_dims=None, base_dims: Optional[Tuple[Tuple[float]]] = None,
code_size=7, code_size: int = 7,
norm_on_bbox=True): norm_on_bbox: bool = True) -> None:
super(FCOS3DBBoxCoder, self).__init__() super(FCOS3DBBoxCoder, self).__init__()
self.base_depths = base_depths self.base_depths = base_depths
self.base_dims = base_dims self.base_dims = base_dims
...@@ -36,7 +39,12 @@ class FCOS3DBBoxCoder(BaseBBoxCoder): ...@@ -36,7 +39,12 @@ class FCOS3DBBoxCoder(BaseBBoxCoder):
# TODO: refactor the encoder in the FCOS3D and PGD head # TODO: refactor the encoder in the FCOS3D and PGD head
pass pass
def decode(self, bbox, scale, stride, training, cls_score=None): def decode(self,
bbox: Tensor,
scale: tuple,
stride: int,
training: bool,
cls_score: Optional[Tensor] = None) -> Tensor:
"""Decode regressed results into 3D predictions. """Decode regressed results into 3D predictions.
Note that offsets are not transformed to the projected 3D centers. Note that offsets are not transformed to the projected 3D centers.
...@@ -100,7 +108,8 @@ class FCOS3DBBoxCoder(BaseBBoxCoder): ...@@ -100,7 +108,8 @@ class FCOS3DBBoxCoder(BaseBBoxCoder):
return bbox return bbox
@staticmethod @staticmethod
def decode_yaw(bbox, centers2d, dir_cls, dir_offset, cam2img): def decode_yaw(bbox: Tensor, centers2d: Tensor, dir_cls: Tensor,
dir_offset: float, cam2img: Tensor) -> Tensor:
"""Decode yaw angle and change it from local to global.i. """Decode yaw angle and change it from local to global.i.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import Dict, List
import numpy as np import numpy as np
import torch import torch
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from mmdet3d.structures.bbox_3d import BaseInstance3DBoxes
from .partial_bin_based_bbox_coder import PartialBinBasedBBoxCoder from .partial_bin_based_bbox_coder import PartialBinBasedBBoxCoder
...@@ -21,11 +25,11 @@ class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder): ...@@ -21,11 +25,11 @@ class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder):
""" """
def __init__(self, def __init__(self,
num_dir_bins, num_dir_bins: int,
num_sizes, num_sizes: int,
mean_sizes, mean_sizes: List[List[int]],
with_rot=True, with_rot: bool = True,
size_cls_agnostic=True): size_cls_agnostic: bool = True) -> None:
super(GroupFree3DBBoxCoder, self).__init__( super(GroupFree3DBBoxCoder, self).__init__(
num_dir_bins=num_dir_bins, num_dir_bins=num_dir_bins,
num_sizes=num_sizes, num_sizes=num_sizes,
...@@ -33,7 +37,8 @@ class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder): ...@@ -33,7 +37,8 @@ class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder):
with_rot=with_rot) with_rot=with_rot)
self.size_cls_agnostic = size_cls_agnostic self.size_cls_agnostic = size_cls_agnostic
def encode(self, gt_bboxes_3d, gt_labels_3d): def encode(self, gt_bboxes_3d: BaseInstance3DBoxes,
gt_labels_3d: Tensor) -> tuple:
"""Encode ground truth to prediction targets. """Encode ground truth to prediction targets.
Args: Args:
...@@ -65,7 +70,7 @@ class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder): ...@@ -65,7 +70,7 @@ class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder):
return (center_target, size_target, size_class_target, size_res_target, return (center_target, size_target, size_class_target, size_res_target,
dir_class_target, dir_res_target) dir_class_target, dir_res_target)
def decode(self, bbox_out, prefix=''): def decode(self, bbox_out: dict, prefix: str = '') -> Tensor:
"""Decode predicted parts to bbox3d. """Decode predicted parts to bbox3d.
Args: Args:
...@@ -116,7 +121,11 @@ class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder): ...@@ -116,7 +121,11 @@ class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder):
bbox3d = torch.cat([center, bbox_size, dir_angle], dim=-1) bbox3d = torch.cat([center, bbox_size, dir_angle], dim=-1)
return bbox3d return bbox3d
def split_pred(self, cls_preds, reg_preds, base_xyz, prefix=''): def split_pred(self,
cls_preds: Tensor,
reg_preds: Tensor,
base_xyz: Tensor,
prefix: str = '') -> Dict[str, Tensor]:
"""Split predicted features to specific parts. """Split predicted features to specific parts.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import Dict, List, Tuple
import numpy as np import numpy as np
import torch import torch
from mmdet.models.task_modules import BaseBBoxCoder from mmdet.models.task_modules import BaseBBoxCoder
from torch import Tensor
from torch.nn import functional as F from torch.nn import functional as F
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from mmdet3d.structures.bbox_3d import BaseInstance3DBoxes
@TASK_UTILS.register_module() @TASK_UTILS.register_module()
...@@ -35,19 +39,19 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -35,19 +39,19 @@ class MonoFlexCoder(BaseBBoxCoder):
""" """
def __init__(self, def __init__(self,
depth_mode, depth_mode: str,
base_depth, base_depth: Tuple[float],
depth_range, depth_range: list,
combine_depth, combine_depth: bool,
uncertainty_range, uncertainty_range: list,
base_dims, base_dims: Tuple[Tuple[float]],
dims_mode, dims_mode: str,
multibin, multibin: bool,
num_dir_bins, num_dir_bins: int,
bin_centers, bin_centers: List[float],
bin_margin, bin_margin: float,
code_size, code_size: int,
eps=1e-3): eps: float = 1e-3) -> None:
super(MonoFlexCoder, self).__init__() super(MonoFlexCoder, self).__init__()
# depth related # depth related
...@@ -71,7 +75,7 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -71,7 +75,7 @@ class MonoFlexCoder(BaseBBoxCoder):
self.bbox_code_size = code_size self.bbox_code_size = code_size
self.eps = eps self.eps = eps
def encode(self, gt_bboxes_3d): def encode(self, gt_bboxes_3d: BaseInstance3DBoxes) -> Tensor:
"""Encode ground truth to prediction targets. """Encode ground truth to prediction targets.
Args: Args:
...@@ -105,7 +109,8 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -105,7 +109,8 @@ class MonoFlexCoder(BaseBBoxCoder):
return orientation_target return orientation_target
def decode(self, bbox, base_centers2d, labels, downsample_ratio, cam2imgs): def decode(self, bbox: Tensor, base_centers2d: Tensor, labels: Tensor,
downsample_ratio: int, cam2imgs: Tensor) -> Dict[str, Tensor]:
"""Decode bounding box regression into 3D predictions. """Decode bounding box regression into 3D predictions.
Args: Args:
...@@ -211,7 +216,7 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -211,7 +216,7 @@ class MonoFlexCoder(BaseBBoxCoder):
return preds return preds
def decode_direct_depth(self, depth_offsets): def decode_direct_depth(self, depth_offsets: Tensor) -> Tensor:
"""Transform depth offset to directly regressed depth. """Transform depth offset to directly regressed depth.
Args: Args:
...@@ -239,12 +244,12 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -239,12 +244,12 @@ class MonoFlexCoder(BaseBBoxCoder):
return direct_depth return direct_depth
def decode_location(self, def decode_location(self,
base_centers2d, base_centers2d: Tensor,
offsets2d, offsets2d: Tensor,
depths, depths: Tensor,
cam2imgs, cam2imgs: Tensor,
downsample_ratio, downsample_ratio: Tensor,
pad_mode='default'): pad_mode: str = 'default') -> Tuple[Tensor]:
"""Retrieve object location. """Retrieve object location.
Args: Args:
...@@ -283,13 +288,15 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -283,13 +288,15 @@ class MonoFlexCoder(BaseBBoxCoder):
return locations[:, :3] return locations[:, :3]
def keypoints2depth(self, def keypoints2depth(
keypoints2d, self,
dimensions, keypoints2d: Tensor,
cam2imgs, dimensions: Tensor,
downsample_ratio=4, cam2imgs: Tensor,
group0_index=[(7, 3), (0, 4)], downsample_ratio: int = 4,
group1_index=[(2, 6), (1, 5)]): group0_index: List[Tuple[int]] = [(7, 3), (0, 4)],
group1_index: List[Tuple[int]] = [(2, 6),
(1, 5)]) -> Tuple[Tensor]:
"""Decode depth form three groups of keypoints and geometry projection """Decode depth form three groups of keypoints and geometry projection
model. 2D keypoints inlucding 8 coreners and top/bottom centers will be model. 2D keypoints inlucding 8 coreners and top/bottom centers will be
divided into three groups which will be used to calculate three depths divided into three groups which will be used to calculate three depths
...@@ -383,7 +390,7 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -383,7 +390,7 @@ class MonoFlexCoder(BaseBBoxCoder):
return keypoints_depth return keypoints_depth
def decode_dims(self, labels, dims_offset): def decode_dims(self, labels: Tensor, dims_offset: Tensor) -> Tensor:
"""Retrieve object dimensions. """Retrieve object dimensions.
Args: Args:
...@@ -411,7 +418,8 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -411,7 +418,8 @@ class MonoFlexCoder(BaseBBoxCoder):
return dimensions return dimensions
def decode_orientation(self, ori_vector, locations): def decode_orientation(self, ori_vector: Tensor,
locations: Tensor) -> Tuple[Tensor]:
"""Retrieve object orientation. """Retrieve object orientation.
Args: Args:
...@@ -467,7 +475,8 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -467,7 +475,8 @@ class MonoFlexCoder(BaseBBoxCoder):
return yaws, local_yaws return yaws, local_yaws
def decode_bboxes2d(self, reg_bboxes2d, base_centers2d): def decode_bboxes2d(self, reg_bboxes2d: Tensor,
base_centers2d: Tensor) -> Tensor:
"""Retrieve [x1, y1, x2, y2] format 2D bboxes. """Retrieve [x1, y1, x2, y2] format 2D bboxes.
Args: Args:
...@@ -492,7 +501,8 @@ class MonoFlexCoder(BaseBBoxCoder): ...@@ -492,7 +501,8 @@ class MonoFlexCoder(BaseBBoxCoder):
return bboxes2d return bboxes2d
def combine_depths(self, depth, depth_uncertainty): def combine_depths(self, depth: Tensor,
depth_uncertainty: Tensor) -> Tensor:
"""Combine all the prediced depths with depth uncertainty. """Combine all the prediced depths with depth uncertainty.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import Dict, List
import numpy as np import numpy as np
import torch import torch
from mmdet.models.task_modules import BaseBBoxCoder from mmdet.models.task_modules import BaseBBoxCoder
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from mmdet3d.structures.bbox_3d import BaseInstance3DBoxes
@TASK_UTILS.register_module() @TASK_UTILS.register_module()
...@@ -17,7 +21,11 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder): ...@@ -17,7 +21,11 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
with_rot (bool): Whether the bbox is with rotation. with_rot (bool): Whether the bbox is with rotation.
""" """
def __init__(self, num_dir_bins, num_sizes, mean_sizes, with_rot=True): def __init__(self,
num_dir_bins: int,
num_sizes: int,
mean_sizes: List[List[int]],
with_rot: bool = True):
super(PartialBinBasedBBoxCoder, self).__init__() super(PartialBinBasedBBoxCoder, self).__init__()
assert len(mean_sizes) == num_sizes assert len(mean_sizes) == num_sizes
self.num_dir_bins = num_dir_bins self.num_dir_bins = num_dir_bins
...@@ -25,7 +33,8 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder): ...@@ -25,7 +33,8 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
self.mean_sizes = mean_sizes self.mean_sizes = mean_sizes
self.with_rot = with_rot self.with_rot = with_rot
def encode(self, gt_bboxes_3d, gt_labels_3d): def encode(self, gt_bboxes_3d: BaseInstance3DBoxes,
gt_labels_3d: Tensor) -> tuple:
"""Encode ground truth to prediction targets. """Encode ground truth to prediction targets.
Args: Args:
...@@ -56,7 +65,7 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder): ...@@ -56,7 +65,7 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
return (center_target, size_class_target, size_res_target, return (center_target, size_class_target, size_res_target,
dir_class_target, dir_res_target) dir_class_target, dir_res_target)
def decode(self, bbox_out, suffix=''): def decode(self, bbox_out: dict, suffix: str = '') -> Tensor:
"""Decode predicted parts to bbox3d. """Decode predicted parts to bbox3d.
Args: Args:
...@@ -99,7 +108,8 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder): ...@@ -99,7 +108,8 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
bbox3d = torch.cat([center, bbox_size, dir_angle], dim=-1) bbox3d = torch.cat([center, bbox_size, dir_angle], dim=-1)
return bbox3d return bbox3d
def decode_corners(self, center, size_res, size_class): def decode_corners(self, center: Tensor, size_res: Tensor,
size_class: Tensor) -> Tensor:
"""Decode center, size residuals and class to corners. Only useful for """Decode center, size residuals and class to corners. Only useful for
axis-aligned bounding boxes, so angle isn't considered. axis-aligned bounding boxes, so angle isn't considered.
...@@ -137,7 +147,8 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder): ...@@ -137,7 +147,8 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
corners = torch.cat([corner1, corner2], dim=-1) corners = torch.cat([corner1, corner2], dim=-1)
return corners return corners
def split_pred(self, cls_preds, reg_preds, base_xyz): def split_pred(self, cls_preds: Tensor, reg_preds: Tensor,
base_xyz: Tensor) -> Dict[str, Tensor]:
"""Split predicted features to specific parts. """Split predicted features to specific parts.
Args: Args:
...@@ -201,7 +212,7 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder): ...@@ -201,7 +212,7 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
return results return results
def angle2class(self, angle): def angle2class(self, angle: Tensor) -> tuple:
"""Convert continuous angle to a discrete class and a residual. """Convert continuous angle to a discrete class and a residual.
Convert continuous angle to a discrete class and a small Convert continuous angle to a discrete class and a small
...@@ -222,7 +233,10 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder): ...@@ -222,7 +233,10 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
angle_cls * angle_per_class + angle_per_class / 2) angle_cls * angle_per_class + angle_per_class / 2)
return angle_cls.long(), angle_res return angle_cls.long(), angle_res
def class2angle(self, angle_cls, angle_res, limit_period=True): def class2angle(self,
angle_cls: Tensor,
angle_res: Tensor,
limit_period: bool = True) -> Tensor:
"""Inverse function to angle2class. """Inverse function to angle2class.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import Tuple
import numpy as np import numpy as np
import torch import torch
from torch import Tensor
from torch.nn import functional as F from torch.nn import functional as F
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
...@@ -16,13 +19,13 @@ class PGDBBoxCoder(FCOS3DBBoxCoder): ...@@ -16,13 +19,13 @@ class PGDBBoxCoder(FCOS3DBBoxCoder):
pass pass
def decode_2d(self, def decode_2d(self,
bbox, bbox: Tensor,
scale, scale: tuple,
stride, stride: int,
max_regress_range, max_regress_range: int,
training, training: bool,
pred_keypoints=False, pred_keypoints: bool = False,
pred_bbox2d=True): pred_bbox2d: bool = True) -> Tensor:
"""Decode regressed 2D attributes. """Decode regressed 2D attributes.
Args: Args:
...@@ -70,8 +73,9 @@ class PGDBBoxCoder(FCOS3DBBoxCoder): ...@@ -70,8 +73,9 @@ class PGDBBoxCoder(FCOS3DBBoxCoder):
bbox[:, -4:] = bbox.clone()[:, -4:].exp() bbox[:, -4:] = bbox.clone()[:, -4:].exp()
return bbox return bbox
def decode_prob_depth(self, depth_cls_preds, depth_range, depth_unit, def decode_prob_depth(self, depth_cls_preds: Tensor,
division, num_depth_cls): depth_range: Tuple[float], depth_unit: int,
division: str, num_depth_cls: int) -> Tensor:
"""Decode probabilistic depth map. """Decode probabilistic depth map.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import List, Optional
import numpy as np import numpy as np
import torch import torch
from mmdet.models.task_modules import BaseBBoxCoder from mmdet.models.task_modules import BaseBBoxCoder
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from mmdet3d.structures import BaseInstance3DBoxes
@TASK_UTILS.register_module() @TASK_UTILS.register_module()
...@@ -18,7 +22,10 @@ class PointXYZWHLRBBoxCoder(BaseBBoxCoder): ...@@ -18,7 +22,10 @@ class PointXYZWHLRBBoxCoder(BaseBBoxCoder):
each class. Defaults to None. each class. Defaults to None.
""" """
def __init__(self, code_size=7, use_mean_size=True, mean_size=None): def __init__(self,
code_size: int = 7,
use_mean_size: bool = True,
mean_size: List[List[float]] = None):
super(PointXYZWHLRBBoxCoder, self).__init__() super(PointXYZWHLRBBoxCoder, self).__init__()
self.code_size = code_size self.code_size = code_size
self.use_mean_size = use_mean_size self.use_mean_size = use_mean_size
...@@ -28,7 +35,10 @@ class PointXYZWHLRBBoxCoder(BaseBBoxCoder): ...@@ -28,7 +35,10 @@ class PointXYZWHLRBBoxCoder(BaseBBoxCoder):
f'The min of mean_size should > 0, however currently it is '\ f'The min of mean_size should > 0, however currently it is '\
f'{self.mean_size.min()}, please check it in your config.' f'{self.mean_size.min()}, please check it in your config.'
def encode(self, gt_bboxes_3d, points, gt_labels_3d=None): def encode(self,
gt_bboxes_3d: BaseInstance3DBoxes,
points: Tensor,
gt_labels_3d: Optional[Tensor] = None) -> Tensor:
"""Encode ground truth to prediction targets. """Encode ground truth to prediction targets.
Args: Args:
...@@ -75,7 +85,10 @@ class PointXYZWHLRBBoxCoder(BaseBBoxCoder): ...@@ -75,7 +85,10 @@ class PointXYZWHLRBBoxCoder(BaseBBoxCoder):
torch.sin(rg), *cgs], torch.sin(rg), *cgs],
dim=-1) dim=-1)
def decode(self, box_encodings, points, pred_labels_3d=None): def decode(self,
box_encodings: Tensor,
points: Tensor,
pred_labels_3d: Optional[Tensor] = None) -> Tensor:
"""Decode predicted parts and points to bbox3d. """Decode predicted parts and points to bbox3d.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import List, Optional, Tuple
import numpy as np import numpy as np
import torch import torch
from mmdet.models.task_modules import BaseBBoxCoder from mmdet.models.task_modules import BaseBBoxCoder
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from mmdet3d.structures import CameraInstance3DBoxes
@TASK_UTILS.register_module() @TASK_UTILS.register_module()
...@@ -17,13 +21,16 @@ class SMOKECoder(BaseBBoxCoder): ...@@ -17,13 +21,16 @@ class SMOKECoder(BaseBBoxCoder):
code_size (int): The dimension of boxes to be encoded. code_size (int): The dimension of boxes to be encoded.
""" """
def __init__(self, base_depth, base_dims, code_size): def __init__(self, base_depth: Tuple[float], base_dims: Tuple[float],
code_size: int):
super(SMOKECoder, self).__init__() super(SMOKECoder, self).__init__()
self.base_depth = base_depth self.base_depth = base_depth
self.base_dims = base_dims self.base_dims = base_dims
self.bbox_code_size = code_size self.bbox_code_size = code_size
def encode(self, locations, dimensions, orientations, input_metas): def encode(self, locations: Optional[Tensor], dimensions: Tensor,
orientations: Tensor,
input_metas: List[dict]) -> CameraInstance3DBoxes:
"""Encode CameraInstance3DBoxes by locations, dimensions, orientations. """Encode CameraInstance3DBoxes by locations, dimensions, orientations.
Args: Args:
...@@ -50,12 +57,12 @@ class SMOKECoder(BaseBBoxCoder): ...@@ -50,12 +57,12 @@ class SMOKECoder(BaseBBoxCoder):
return batch_bboxes return batch_bboxes
def decode(self, def decode(self,
reg, reg: Tensor,
points, points: Tensor,
labels, labels: Tensor,
cam2imgs, cam2imgs: Tensor,
trans_mats, trans_mats: Tensor,
locations=None): locations: Optional[Tensor] = None) -> Tuple[Tensor]:
"""Decode regression into locations, dimensions, orientations. """Decode regression into locations, dimensions, orientations.
Args: Args:
...@@ -104,15 +111,16 @@ class SMOKECoder(BaseBBoxCoder): ...@@ -104,15 +111,16 @@ class SMOKECoder(BaseBBoxCoder):
return pred_locations, pred_dimensions, pred_orientations return pred_locations, pred_dimensions, pred_orientations
def _decode_depth(self, depth_offsets): def _decode_depth(self, depth_offsets: Tensor) -> Tensor:
"""Transform depth offset to depth.""" """Transform depth offset to depth."""
base_depth = depth_offsets.new_tensor(self.base_depth) base_depth = depth_offsets.new_tensor(self.base_depth)
depths = depth_offsets * base_depth[1] + base_depth[0] depths = depth_offsets * base_depth[1] + base_depth[0]
return depths return depths
def _decode_location(self, points, centers2d_offsets, depths, cam2imgs, def _decode_location(self, points: Tensor, centers2d_offsets: Tensor,
trans_mats): depths: Tensor, cam2imgs: Tensor,
trans_mats: Tensor) -> Tensor:
"""Retrieve objects location in camera coordinate based on projected """Retrieve objects location in camera coordinate based on projected
points. points.
...@@ -152,7 +160,7 @@ class SMOKECoder(BaseBBoxCoder): ...@@ -152,7 +160,7 @@ class SMOKECoder(BaseBBoxCoder):
return locations[:, :3] return locations[:, :3]
def _decode_dimension(self, labels, dims_offset): def _decode_dimension(self, labels: Tensor, dims_offset: Tensor) -> Tensor:
"""Transform dimension offsets to dimension according to its category. """Transform dimension offsets to dimension according to its category.
Args: Args:
...@@ -168,7 +176,8 @@ class SMOKECoder(BaseBBoxCoder): ...@@ -168,7 +176,8 @@ class SMOKECoder(BaseBBoxCoder):
return dimensions return dimensions
def _decode_orientation(self, ori_vector, locations): def _decode_orientation(self, ori_vector: Tensor,
locations: Optional[Tensor]) -> Tensor:
"""Retrieve object orientation. """Retrieve object orientation.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import math import math
from typing import Optional, Union
import torch import torch
from mmdet.models.task_modules import AssignResult
from numpy import ndarray
from torch import Tensor
from mmdet3d.registry import TASK_UTILS from mmdet3d.registry import TASK_UTILS
from . import RandomSampler, SamplingResult from . import RandomSampler, SamplingResult
...@@ -29,13 +33,13 @@ class IoUNegPiecewiseSampler(RandomSampler): ...@@ -29,13 +33,13 @@ class IoUNegPiecewiseSampler(RandomSampler):
""" """
def __init__(self, def __init__(self,
num, num: int,
pos_fraction=None, pos_fraction: Optional[float] = None,
neg_piece_fractions=None, neg_piece_fractions: Optional[list] = None,
neg_iou_piece_thrs=None, neg_iou_piece_thrs: Optional[list] = None,
neg_pos_ub=-1, neg_pos_ub: float = -1,
add_gt_as_proposals=False, add_gt_as_proposals: bool = False,
return_iou=False): return_iou: bool = False) -> None:
super(IoUNegPiecewiseSampler, super(IoUNegPiecewiseSampler,
self).__init__(num, pos_fraction, neg_pos_ub, self).__init__(num, pos_fraction, neg_pos_ub,
add_gt_as_proposals) add_gt_as_proposals)
...@@ -46,7 +50,8 @@ class IoUNegPiecewiseSampler(RandomSampler): ...@@ -46,7 +50,8 @@ class IoUNegPiecewiseSampler(RandomSampler):
self.return_iou = return_iou self.return_iou = return_iou
self.neg_piece_num = len(self.neg_piece_fractions) self.neg_piece_num = len(self.neg_piece_fractions)
def _sample_pos(self, assign_result, num_expected, **kwargs): def _sample_pos(self, assign_result: AssignResult, num_expected: int,
**kwargs) -> Union[Tensor, ndarray]:
"""Randomly sample some positive samples.""" """Randomly sample some positive samples."""
pos_inds = torch.nonzero(assign_result.gt_inds > 0, as_tuple=False) pos_inds = torch.nonzero(assign_result.gt_inds > 0, as_tuple=False)
if pos_inds.numel() != 0: if pos_inds.numel() != 0:
...@@ -56,7 +61,8 @@ class IoUNegPiecewiseSampler(RandomSampler): ...@@ -56,7 +61,8 @@ class IoUNegPiecewiseSampler(RandomSampler):
else: else:
return self.random_choice(pos_inds, num_expected) return self.random_choice(pos_inds, num_expected)
def _sample_neg(self, assign_result, num_expected, **kwargs): def _sample_neg(self, assign_result: AssignResult, num_expected: int,
**kwargs) -> Tensor:
"""Randomly sample some negative samples.""" """Randomly sample some negative samples."""
neg_inds = torch.nonzero(assign_result.gt_inds == 0, as_tuple=False) neg_inds = torch.nonzero(assign_result.gt_inds == 0, as_tuple=False)
if neg_inds.numel() != 0: if neg_inds.numel() != 0:
...@@ -127,11 +133,11 @@ class IoUNegPiecewiseSampler(RandomSampler): ...@@ -127,11 +133,11 @@ class IoUNegPiecewiseSampler(RandomSampler):
return neg_inds_choice return neg_inds_choice
def sample(self, def sample(self,
assign_result, assign_result: AssignResult,
bboxes, bboxes: Tensor,
gt_bboxes, gt_bboxes: Tensor,
gt_labels=None, gt_labels: Optional[Tensor] = None,
**kwargs): **kwargs) -> SamplingResult:
"""Sample positive and negative bboxes. """Sample positive and negative bboxes.
This is a simple implementation of bbox sampling given candidates, This is a simple implementation of bbox sampling given candidates,
......
...@@ -25,7 +25,7 @@ class PseudoSampler(BaseSampler): ...@@ -25,7 +25,7 @@ class PseudoSampler(BaseSampler):
raise NotImplementedError raise NotImplementedError
def sample(self, assign_result: AssignResult, pred_instances: InstanceData, def sample(self, assign_result: AssignResult, pred_instances: InstanceData,
gt_instances: InstanceData, *args, **kwargs): gt_instances: InstanceData, *args, **kwargs) -> SamplingResult:
"""Directly returns the positive and negative indices of samples. """Directly returns the positive and negative indices of samples.
Args: Args:
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from typing import List, Tuple, Union
import numba import numba
import numpy as np import numpy as np
...@@ -18,10 +20,10 @@ class VoxelGenerator(object): ...@@ -18,10 +20,10 @@ class VoxelGenerator(object):
""" """
def __init__(self, def __init__(self,
voxel_size, voxel_size: List[float],
point_cloud_range, point_cloud_range: List[float],
max_num_points, max_num_points: int,
max_voxels=20000): max_voxels: int = 20000):
point_cloud_range = np.array(point_cloud_range, dtype=np.float32) point_cloud_range = np.array(point_cloud_range, dtype=np.float32)
# [0, -40, -3, 70.4, 40, 1] # [0, -40, -3, 70.4, 40, 1]
...@@ -36,33 +38,33 @@ class VoxelGenerator(object): ...@@ -36,33 +38,33 @@ class VoxelGenerator(object):
self._max_voxels = max_voxels self._max_voxels = max_voxels
self._grid_size = grid_size self._grid_size = grid_size
def generate(self, points): def generate(self, points: np.ndarray) -> Tuple[np.ndarray]:
"""Generate voxels given points.""" """Generate voxels given points."""
return points_to_voxel(points, self._voxel_size, return points_to_voxel(points, self._voxel_size,
self._point_cloud_range, self._max_num_points, self._point_cloud_range, self._max_num_points,
True, self._max_voxels) True, self._max_voxels)
@property @property
def voxel_size(self): def voxel_size(self) -> List[float]:
"""list[float]: Size of a single voxel.""" """list[float]: Size of a single voxel."""
return self._voxel_size return self._voxel_size
@property @property
def max_num_points_per_voxel(self): def max_num_points_per_voxel(self) -> int:
"""int: Maximum number of points per voxel.""" """int: Maximum number of points per voxel."""
return self._max_num_points return self._max_num_points
@property @property
def point_cloud_range(self): def point_cloud_range(self) -> List[float]:
"""list[float]: Range of point cloud.""" """list[float]: Range of point cloud."""
return self._point_cloud_range return self._point_cloud_range
@property @property
def grid_size(self): def grid_size(self) -> np.ndarray:
"""np.ndarray: The size of grids.""" """np.ndarray: The size of grids."""
return self._grid_size return self._grid_size
def __repr__(self): def __repr__(self) -> str:
"""str: Return a string that describes the module.""" """str: Return a string that describes the module."""
repr_str = self.__class__.__name__ repr_str = self.__class__.__name__
indent = ' ' * (len(repr_str) + 1) indent = ' ' * (len(repr_str) + 1)
...@@ -76,12 +78,13 @@ class VoxelGenerator(object): ...@@ -76,12 +78,13 @@ class VoxelGenerator(object):
return repr_str return repr_str
def points_to_voxel(points, def points_to_voxel(points: np.ndarray,
voxel_size, voxel_size: Union[list, tuple, np.ndarray],
coors_range, coors_range: Union[List[float], List[Tuple[float]],
max_points=35, List[np.ndarray]],
reverse_index=True, max_points: int = 35,
max_voxels=20000): reverse_index: bool = True,
max_voxels: int = 20000) -> Tuple[np.ndarray]:
"""convert kitti points(N, >=3) to voxels. """convert kitti points(N, >=3) to voxels.
Args: Args:
...@@ -138,15 +141,17 @@ def points_to_voxel(points, ...@@ -138,15 +141,17 @@ def points_to_voxel(points,
@numba.jit(nopython=True) @numba.jit(nopython=True)
def _points_to_voxel_reverse_kernel(points, def _points_to_voxel_reverse_kernel(points: np.ndarray,
voxel_size, voxel_size: Union[list, tuple, np.ndarray],
coors_range, coors_range: Union[List[float],
num_points_per_voxel, List[Tuple[float]],
coor_to_voxelidx, List[np.ndarray]],
voxels, num_points_per_voxel: int,
coors, coor_to_voxelidx: np.ndarray,
max_points=35, voxels: np.ndarray,
max_voxels=20000): coors: np.ndarray,
max_points: int = 35,
max_voxels: int = 20000):
"""convert kitti points(N, >=3) to voxels. """convert kitti points(N, >=3) to voxels.
Args: Args:
...@@ -212,15 +217,16 @@ def _points_to_voxel_reverse_kernel(points, ...@@ -212,15 +217,16 @@ def _points_to_voxel_reverse_kernel(points,
@numba.jit(nopython=True) @numba.jit(nopython=True)
def _points_to_voxel_kernel(points, def _points_to_voxel_kernel(points: np.ndarray,
voxel_size, voxel_size: Union[list, tuple, np.ndarray],
coors_range, coors_range: Union[List[float], List[Tuple[float]],
num_points_per_voxel, List[np.ndarray]],
coor_to_voxelidx, num_points_per_voxel: int,
voxels, coor_to_voxelidx: np.ndarray,
coors, voxels: np.ndarray,
max_points=35, coors: np.ndarray,
max_voxels=20000): max_points: int = 35,
max_voxels: int = 200000):
"""convert kitti points(N, >=3) to voxels. """convert kitti points(N, >=3) to voxels.
Args: Args:
...@@ -230,7 +236,7 @@ def _points_to_voxel_kernel(points, ...@@ -230,7 +236,7 @@ def _points_to_voxel_kernel(points,
coors_range (list[float | tuple[float] | ndarray]): Range of voxels. coors_range (list[float | tuple[float] | ndarray]): Range of voxels.
format: xyzxyz, minmax format: xyzxyz, minmax
num_points_per_voxel (int): Number of points per voxel. num_points_per_voxel (int): Number of points per voxel.
coor_to_voxel_idx (np.ndarray): A voxel grid of shape (D, H, W), coor_to_voxelidx (np.ndarray): A voxel grid of shape (D, H, W),
which has the same shape as the complete voxel map. It indicates which has the same shape as the complete voxel map. It indicates
the index of each corresponding voxel. the index of each corresponding voxel.
voxels (np.ndarray): Created empty voxels. voxels (np.ndarray): Created empty voxels.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment