Commit 80b39bd0 authored by zhangwenwei's avatar zhangwenwei
Browse files

Reformat docstrings in code

parent 64d7fbc2
yapf -r -i --style .style.yapf mmdet3d/ configs/ tests/ tools/ yapf -r -i --style .style.yapf mmdet3d/ configs/ tests/ tools/
isort -rc mmdet3d/ configs/ tests/ tools/ isort mmdet3d/ configs/ tests/ tools/
flake8 . flake8 .
...@@ -20,7 +20,7 @@ linting: ...@@ -20,7 +20,7 @@ linting:
script: script:
- pip install flake8==3.7.9 yapf isort - pip install flake8==3.7.9 yapf isort
- flake8 . - flake8 .
- isort -rc --check-only --diff mmdet3d/ tools/ tests/ - isort --check-only --diff mmdet3d/ tools/ tests/
- yapf -r -d mmdet3d/ tools/ tests/ configs/ - yapf -r -d mmdet3d/ tools/ tests/ configs/
.test_template: &test_template_def .test_template: &test_template_def
......
repos: repos:
- repo: https://gitlab.com/pycqa/flake8.git - repo: https://gitlab.com/pycqa/flake8.git
rev: 3.7.9 rev: 3.8.3
hooks: hooks:
- id: flake8 - id: flake8
- repo: https://github.com/asottile/seed-isort-config - repo: https://github.com/asottile/seed-isort-config
rev: v2.1.0 rev: v2.2.0
hooks: hooks:
- id: seed-isort-config - id: seed-isort-config
- repo: https://github.com/timothycrosley/isort - repo: https://github.com/timothycrosley/isort
rev: 4.3.21 rev: 5.0.2
hooks: hooks:
- id: isort - id: isort
- repo: https://github.com/pre-commit/mirrors-yapf - repo: https://github.com/pre-commit/mirrors-yapf
rev: v0.30.0 rev: v0.30.0
hooks: hooks:
- id: yapf - id: yapf
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.5.0 rev: v3.1.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: check-yaml - id: check-yaml
...@@ -27,3 +26,10 @@ repos: ...@@ -27,3 +26,10 @@ repos:
- id: check-merge-conflict - id: check-merge-conflict
- id: fix-encoding-pragma - id: fix-encoding-pragma
args: ["--remove"] args: ["--remove"]
- id: mixed-line-ending
args: ["--fix=lf"]
- repo: https://github.com/myint/docformatter
rev: v1.3.1
hooks:
- id: docformatter
args: ["--in-place", "--wrap-descriptions", "79"]
import os.path as osp
from copy import deepcopy
import mmcv import mmcv
import torch import torch
from copy import deepcopy
from mmcv.parallel import collate, scatter from mmcv.parallel import collate, scatter
from mmcv.runner import load_checkpoint from mmcv.runner import load_checkpoint
from os import path as osp
from mmdet3d.core import Box3DMode, show_result from mmdet3d.core import Box3DMode, show_result
from mmdet3d.core.bbox import get_box_type from mmdet3d.core.bbox import get_box_type
......
...@@ -6,7 +6,7 @@ from mmdet.core.anchor import ANCHOR_GENERATORS ...@@ -6,7 +6,7 @@ from mmdet.core.anchor import ANCHOR_GENERATORS
@ANCHOR_GENERATORS.register_module() @ANCHOR_GENERATORS.register_module()
class Anchor3DRangeGenerator(object): class Anchor3DRangeGenerator(object):
"""3D Anchor Generator by range """3D Anchor Generator by range.
This anchor generator generates anchors by the given range in different This anchor generator generates anchors by the given range in different
feature levels. feature levels.
...@@ -80,7 +80,7 @@ class Anchor3DRangeGenerator(object): ...@@ -80,7 +80,7 @@ class Anchor3DRangeGenerator(object):
return len(self.scales) return len(self.scales)
def grid_anchors(self, featmap_sizes, device='cuda'): def grid_anchors(self, featmap_sizes, device='cuda'):
"""Generate grid anchors in multiple feature levels """Generate grid anchors in multiple feature levels.
Args: Args:
featmap_sizes (list[tuple]): List of feature map sizes in featmap_sizes (list[tuple]): List of feature map sizes in
...@@ -152,7 +152,7 @@ class Anchor3DRangeGenerator(object): ...@@ -152,7 +152,7 @@ class Anchor3DRangeGenerator(object):
sizes=[[1.6, 3.9, 1.56]], sizes=[[1.6, 3.9, 1.56]],
rotations=[0, 1.5707963], rotations=[0, 1.5707963],
device='cuda'): device='cuda'):
"""Generate anchors in a single range """Generate anchors in a single range.
Args: Args:
feature_size (list[float] | tuple[float]): Feature map size. It is feature_size (list[float] | tuple[float]): Feature map size. It is
...@@ -212,7 +212,7 @@ class Anchor3DRangeGenerator(object): ...@@ -212,7 +212,7 @@ class Anchor3DRangeGenerator(object):
@ANCHOR_GENERATORS.register_module() @ANCHOR_GENERATORS.register_module()
class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator): class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator):
"""Aligned 3D Anchor Generator by range """Aligned 3D Anchor Generator by range.
This anchor generator uses a different manner to generate the positions This anchor generator uses a different manner to generate the positions
of anchors' centers from `Anchor3DRangeGenerator`. of anchors' centers from `Anchor3DRangeGenerator`.
...@@ -247,7 +247,7 @@ class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator): ...@@ -247,7 +247,7 @@ class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator):
sizes=[[1.6, 3.9, 1.56]], sizes=[[1.6, 3.9, 1.56]],
rotations=[0, 1.5707963], rotations=[0, 1.5707963],
device='cuda'): device='cuda'):
"""Generate anchors in a single range """Generate anchors in a single range.
Args: Args:
feature_size: list [D, H, W](zyx) feature_size: list [D, H, W](zyx)
......
...@@ -22,8 +22,7 @@ def box_camera_to_lidar(data, r_rect, velo2cam): ...@@ -22,8 +22,7 @@ def box_camera_to_lidar(data, r_rect, velo2cam):
def corners_nd(dims, origin=0.5): def corners_nd(dims, origin=0.5):
"""Generate relative box corners based on length per dim and """Generate relative box corners based on length per dim and origin point.
origin point.
Args: Args:
dims (np.ndarray, shape=[N, ndim]): Array of length per dim dims (np.ndarray, shape=[N, ndim]): Array of length per dim
...@@ -206,8 +205,8 @@ def corner_to_standup_nd_jit(boxes_corner): ...@@ -206,8 +205,8 @@ def corner_to_standup_nd_jit(boxes_corner):
@numba.jit(nopython=True) @numba.jit(nopython=True)
def corner_to_surfaces_3d_jit(corners): def corner_to_surfaces_3d_jit(corners):
"""Convert 3d box corners from corner function above """Convert 3d box corners from corner function above to surfaces that
to surfaces that normal vectors all direct to internal. normal vectors all direct to internal.
Args: Args:
corners (np.ndarray, [N, 8, 3]): 3d box corners corners (np.ndarray, [N, 8, 3]): 3d box corners
...@@ -272,8 +271,8 @@ def box3d_to_bbox(box3d, rect, Trv2c, P2): ...@@ -272,8 +271,8 @@ def box3d_to_bbox(box3d, rect, Trv2c, P2):
def corner_to_surfaces_3d(corners): def corner_to_surfaces_3d(corners):
"""convert 3d box corners from corner function above """convert 3d box corners from corner function above to surfaces that
to surfaces that normal vectors all direct to internal. normal vectors all direct to internal.
Args: Args:
corners (np.ndarray, [N, 8, 3]): 3d box corners. corners (np.ndarray, [N, 8, 3]): 3d box corners.
......
...@@ -6,7 +6,7 @@ from mmdet.core.bbox.builder import BBOX_CODERS ...@@ -6,7 +6,7 @@ from mmdet.core.bbox.builder import BBOX_CODERS
@BBOX_CODERS.register_module() @BBOX_CODERS.register_module()
class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder): class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder):
"""Bbox Coder for 3D boxes """Bbox Coder for 3D boxes.
Args: Args:
code_size (int): The dimension of boxes to be encoded. code_size (int): The dimension of boxes to be encoded.
...@@ -18,9 +18,9 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder): ...@@ -18,9 +18,9 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder):
@staticmethod @staticmethod
def encode(src_boxes, dst_boxes): def encode(src_boxes, dst_boxes):
"""Get box regression transformation deltas """Get box regression transformation deltas (dx, dy, dz, dw, dh, dl,
(dx, dy, dz, dw, dh, dl, dr, dv*) that can be used dr, dv*) that can be used to transform the `src_boxes` into the
to transform the `src_boxes` into the `target_boxes`. `target_boxes`.
Args: Args:
src_boxes (torch.Tensor): source boxes, e.g., object proposals. src_boxes (torch.Tensor): source boxes, e.g., object proposals.
...@@ -55,7 +55,8 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder): ...@@ -55,7 +55,8 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder):
@staticmethod @staticmethod
def decode(anchors, deltas): def decode(anchors, deltas):
"""Apply transformation `deltas` (dx, dy, dz, dw, dh, dl, dr, dv*) to `boxes`. """Apply transformation `deltas` (dx, dy, dz, dw, dh, dl, dr, dv*) to
`boxes`.
Args: Args:
anchors (torch.Tensor): Parameters of anchors with shape (N, 7). anchors (torch.Tensor): Parameters of anchors with shape (N, 7).
......
...@@ -7,7 +7,7 @@ from mmdet.core.bbox.builder import BBOX_CODERS ...@@ -7,7 +7,7 @@ from mmdet.core.bbox.builder import BBOX_CODERS
@BBOX_CODERS.register_module() @BBOX_CODERS.register_module()
class PartialBinBasedBBoxCoder(BaseBBoxCoder): class PartialBinBasedBBoxCoder(BaseBBoxCoder):
"""Partial bin based bbox coder """Partial bin based bbox coder.
Args: Args:
num_dir_bins (int): Number of bins to encode direction angle. num_dir_bins (int): Number of bins to encode direction angle.
...@@ -175,7 +175,7 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder): ...@@ -175,7 +175,7 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
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, angle_res, limit_period=True):
"""Inverse function to angle2class """Inverse function to angle2class.
Args: Args:
angle_cls (torch.Tensor): Angle class to decode. angle_cls (torch.Tensor): Angle class to decode.
......
...@@ -5,7 +5,7 @@ from ..structures import get_box_type ...@@ -5,7 +5,7 @@ from ..structures import get_box_type
@IOU_CALCULATORS.register_module() @IOU_CALCULATORS.register_module()
class BboxOverlapsNearest3D(object): class BboxOverlapsNearest3D(object):
"""Nearest 3D IoU Calculator """Nearest 3D IoU Calculator.
Note: Note:
This IoU calculator first finds the nearest 2D boxes in bird eye view This IoU calculator first finds the nearest 2D boxes in bird eye view
...@@ -20,7 +20,7 @@ class BboxOverlapsNearest3D(object): ...@@ -20,7 +20,7 @@ class BboxOverlapsNearest3D(object):
self.coordinate = coordinate self.coordinate = coordinate
def __call__(self, bboxes1, bboxes2, mode='iou', is_aligned=False): def __call__(self, bboxes1, bboxes2, mode='iou', is_aligned=False):
"""Calculate nearest 3D IoU """Calculate nearest 3D IoU.
Note: Note:
If ``is_aligned`` is ``False``, then it calculates the ious between If ``is_aligned`` is ``False``, then it calculates the ious between
...@@ -51,7 +51,7 @@ class BboxOverlapsNearest3D(object): ...@@ -51,7 +51,7 @@ class BboxOverlapsNearest3D(object):
@IOU_CALCULATORS.register_module() @IOU_CALCULATORS.register_module()
class BboxOverlaps3D(object): class BboxOverlaps3D(object):
"""3D IoU Calculator """3D IoU Calculator.
Args: Args:
coordinate (str): The coordinate system, valid options are coordinate (str): The coordinate system, valid options are
...@@ -63,7 +63,7 @@ class BboxOverlaps3D(object): ...@@ -63,7 +63,7 @@ class BboxOverlaps3D(object):
self.coordinate = coordinate self.coordinate = coordinate
def __call__(self, bboxes1, bboxes2, mode='iou'): def __call__(self, bboxes1, bboxes2, mode='iou'):
"""Calculate 3D IoU using cuda implementation """Calculate 3D IoU using cuda implementation.
Note: Note:
This function calculate the IoU of 3D boxes based on their volumes. This function calculate the IoU of 3D boxes based on their volumes.
...@@ -94,7 +94,7 @@ def bbox_overlaps_nearest_3d(bboxes1, ...@@ -94,7 +94,7 @@ def bbox_overlaps_nearest_3d(bboxes1,
mode='iou', mode='iou',
is_aligned=False, is_aligned=False,
coordinate='lidar'): coordinate='lidar'):
"""Calculate nearest 3D IoU """Calculate nearest 3D IoU.
Note: Note:
This function first finds the nearest 2D boxes in bird eye view This function first finds the nearest 2D boxes in bird eye view
...@@ -117,7 +117,6 @@ def bbox_overlaps_nearest_3d(bboxes1, ...@@ -117,7 +117,6 @@ def bbox_overlaps_nearest_3d(bboxes1,
torch.Tensor: If ``is_aligned`` is ``True``, return ious between torch.Tensor: If ``is_aligned`` is ``True``, return ious between
bboxes1 and bboxes2 with shape (M, N). If ``is_aligned`` is bboxes1 and bboxes2 with shape (M, N). If ``is_aligned`` is
``False``, return shape is M. ``False``, return shape is M.
""" """
assert bboxes1.size(-1) == bboxes2.size(-1) >= 7 assert bboxes1.size(-1) == bboxes2.size(-1) >= 7
...@@ -138,7 +137,7 @@ def bbox_overlaps_nearest_3d(bboxes1, ...@@ -138,7 +137,7 @@ def bbox_overlaps_nearest_3d(bboxes1,
def bbox_overlaps_3d(bboxes1, bboxes2, mode='iou', coordinate='camera'): def bbox_overlaps_3d(bboxes1, bboxes2, mode='iou', coordinate='camera'):
"""Calculate 3D IoU using cuda implementation """Calculate 3D IoU using cuda implementation.
Note: Note:
This function calculate the IoU of 3D boxes based on their volumes. This function calculate the IoU of 3D boxes based on their volumes.
......
from abc import abstractmethod
import numpy as np import numpy as np
import torch import torch
from abc import abstractmethod
from mmdet3d.ops.iou3d import iou3d_cuda from mmdet3d.ops.iou3d import iou3d_cuda
from .utils import limit_period, xywhr2xyxyr from .utils import limit_period, xywhr2xyxyr
class BaseInstance3DBoxes(object): class BaseInstance3DBoxes(object):
"""Base class for 3D Boxes """Base class for 3D Boxes.
Note: Note:
The box is bottom centered, i.e. the relative position of origin in The box is bottom centered, i.e. the relative position of origin in
...@@ -162,7 +161,7 @@ class BaseInstance3DBoxes(object): ...@@ -162,7 +161,7 @@ class BaseInstance3DBoxes(object):
@abstractmethod @abstractmethod
def rotate(self, angles, axis=0): def rotate(self, angles, axis=0):
"""Calculate whether the points is in any of the boxes """Calculate whether the points is in any of the boxes.
Args: Args:
angles (float): rotation angles angles (float): rotation angles
...@@ -172,12 +171,11 @@ class BaseInstance3DBoxes(object): ...@@ -172,12 +171,11 @@ class BaseInstance3DBoxes(object):
@abstractmethod @abstractmethod
def flip(self, bev_direction='horizontal'): def flip(self, bev_direction='horizontal'):
"""Flip the boxes in BEV along given BEV direction """Flip the boxes in BEV along given BEV direction."""
"""
pass pass
def translate(self, trans_vector): def translate(self, trans_vector):
"""Calculate whether the points is in any of the boxes """Calculate whether the points is in any of the boxes.
Args: Args:
trans_vector (torch.Tensor): translation vector of size 1x3 trans_vector (torch.Tensor): translation vector of size 1x3
...@@ -187,7 +185,7 @@ class BaseInstance3DBoxes(object): ...@@ -187,7 +185,7 @@ class BaseInstance3DBoxes(object):
self.tensor[:, :3] += trans_vector self.tensor[:, :3] += trans_vector
def in_range_3d(self, box_range): def in_range_3d(self, box_range):
"""Check whether the boxes are in the given range """Check whether the boxes are in the given range.
Args: Args:
box_range (list | torch.Tensor): the range of box box_range (list | torch.Tensor): the range of box
...@@ -213,7 +211,7 @@ class BaseInstance3DBoxes(object): ...@@ -213,7 +211,7 @@ class BaseInstance3DBoxes(object):
@abstractmethod @abstractmethod
def in_range_bev(self, box_range): def in_range_bev(self, box_range):
"""Check whether the boxes are in the given range """Check whether the boxes are in the given range.
Args: Args:
box_range (list | torch.Tensor): the range of box box_range (list | torch.Tensor): the range of box
...@@ -244,7 +242,7 @@ class BaseInstance3DBoxes(object): ...@@ -244,7 +242,7 @@ class BaseInstance3DBoxes(object):
pass pass
def scale(self, scale_factor): def scale(self, scale_factor):
"""Scale the box with horizontal and vertical scaling factors """Scale the box with horizontal and vertical scaling factors.
Args: Args:
scale_factors (float): Scale factors to scale the boxes. scale_factors (float): Scale factors to scale the boxes.
...@@ -253,7 +251,7 @@ class BaseInstance3DBoxes(object): ...@@ -253,7 +251,7 @@ class BaseInstance3DBoxes(object):
self.tensor[:, 7:] *= scale_factor self.tensor[:, 7:] *= scale_factor
def limit_yaw(self, offset=0.5, period=np.pi): def limit_yaw(self, offset=0.5, period=np.pi):
"""Limit the yaw to a given period and offset """Limit the yaw to a given period and offset.
Args: Args:
offset (float): The offset of the yaw. offset (float): The offset of the yaw.
...@@ -321,7 +319,7 @@ class BaseInstance3DBoxes(object): ...@@ -321,7 +319,7 @@ class BaseInstance3DBoxes(object):
@classmethod @classmethod
def cat(cls, boxes_list): def cat(cls, boxes_list):
"""Concatenates a list of Boxes into a single Boxes """Concatenates a list of Boxes into a single Boxes.
Args: Args:
boxes_list (list[Boxes]): List of boxes. boxes_list (list[Boxes]): List of boxes.
...@@ -343,7 +341,7 @@ class BaseInstance3DBoxes(object): ...@@ -343,7 +341,7 @@ class BaseInstance3DBoxes(object):
return cat_boxes return cat_boxes
def to(self, device): def to(self, device):
"""Convert current boxes to a specific device """Convert current boxes to a specific device.
Args: Args:
device (str | :obj:`torch.device`): The name of the device. device (str | :obj:`torch.device`): The name of the device.
...@@ -383,7 +381,7 @@ class BaseInstance3DBoxes(object): ...@@ -383,7 +381,7 @@ class BaseInstance3DBoxes(object):
@classmethod @classmethod
def height_overlaps(cls, boxes1, boxes2, mode='iou'): def height_overlaps(cls, boxes1, boxes2, mode='iou'):
"""Calculate height overlaps of two boxes """Calculate height overlaps of two boxes.
Note: Note:
This function calculate the height overlaps between boxes1 and This function calculate the height overlaps between boxes1 and
...@@ -415,7 +413,7 @@ class BaseInstance3DBoxes(object): ...@@ -415,7 +413,7 @@ class BaseInstance3DBoxes(object):
@classmethod @classmethod
def overlaps(cls, boxes1, boxes2, mode='iou'): def overlaps(cls, boxes1, boxes2, mode='iou'):
"""Calculate 3D overlaps of two boxes """Calculate 3D overlaps of two boxes.
Note: Note:
This function calculate the overlaps between boxes1 and boxes2, This function calculate the overlaps between boxes1 and boxes2,
......
from enum import IntEnum, unique
import numpy as np import numpy as np
import torch import torch
from enum import IntEnum, unique
from .base_box3d import BaseInstance3DBoxes from .base_box3d import BaseInstance3DBoxes
from .cam_box3d import CameraInstance3DBoxes from .cam_box3d import CameraInstance3DBoxes
......
...@@ -121,7 +121,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes): ...@@ -121,7 +121,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
@property @property
def bev(self): def bev(self):
"""Calculate the 2D bounding boxes in BEV with rotation """Calculate the 2D bounding boxes in BEV with rotation.
Returns: Returns:
torch.Tensor: A nx5 tensor of 2D BEV box of each box. torch.Tensor: A nx5 tensor of 2D BEV box of each box.
...@@ -131,7 +131,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes): ...@@ -131,7 +131,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
@property @property
def nearest_bev(self): def nearest_bev(self):
"""Calculate the 2D bounding boxes in BEV without rotation """Calculate the 2D bounding boxes in BEV without rotation.
Returns: Returns:
torch.Tensor: A tensor of 2D BEV box of each box. torch.Tensor: A tensor of 2D BEV box of each box.
...@@ -187,7 +187,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes): ...@@ -187,7 +187,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
return points, rot_mat_T return points, rot_mat_T
def flip(self, bev_direction='horizontal', points=None): def flip(self, bev_direction='horizontal', points=None):
"""Flip the boxes in BEV along given BEV direction """Flip the boxes in BEV along given BEV direction.
In CAM coordinates, it flips the x (horizontal) or z (vertical) axis. In CAM coordinates, it flips the x (horizontal) or z (vertical) axis.
...@@ -218,7 +218,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes): ...@@ -218,7 +218,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
return points return points
def in_range_bev(self, box_range): def in_range_bev(self, box_range):
"""Check whether the boxes are in the given range """Check whether the boxes are in the given range.
Args: Args:
box_range (list | torch.Tensor): The range of box box_range (list | torch.Tensor): The range of box
...@@ -242,7 +242,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes): ...@@ -242,7 +242,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
@classmethod @classmethod
def height_overlaps(cls, boxes1, boxes2, mode='iou'): def height_overlaps(cls, boxes1, boxes2, mode='iou'):
"""Calculate height overlaps of two boxes """Calculate height overlaps of two boxes.
Note: Note:
This function calculate the height overlaps between boxes1 and This function calculate the height overlaps between boxes1 and
......
...@@ -165,7 +165,7 @@ class DepthInstance3DBoxes(BaseInstance3DBoxes): ...@@ -165,7 +165,7 @@ class DepthInstance3DBoxes(BaseInstance3DBoxes):
return points, rot_mat_T return points, rot_mat_T
def flip(self, bev_direction='horizontal', points=None): def flip(self, bev_direction='horizontal', points=None):
"""Flip the boxes in BEV along given BEV direction """Flip the boxes in BEV along given BEV direction.
In Depth coordinates, it flips x (horizontal) or y (vertical) axis. In Depth coordinates, it flips x (horizontal) or y (vertical) axis.
......
...@@ -7,7 +7,7 @@ from .utils import limit_period, rotation_3d_in_axis ...@@ -7,7 +7,7 @@ from .utils import limit_period, rotation_3d_in_axis
class LiDARInstance3DBoxes(BaseInstance3DBoxes): class LiDARInstance3DBoxes(BaseInstance3DBoxes):
"""3D boxes of instances in LIDAR coordinates """3D boxes of instances in LIDAR coordinates.
Coordinates in LiDAR: Coordinates in LiDAR:
.. code-block:: none .. code-block:: none
...@@ -89,7 +89,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes): ...@@ -89,7 +89,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes):
@property @property
def bev(self): def bev(self):
"""Calculate the 2D bounding boxes in BEV with rotation """Calculate the 2D bounding boxes in BEV with rotation.
Returns: Returns:
torch.Tensor: A nx5 tensor of 2D BEV box of each box. torch.Tensor: A nx5 tensor of 2D BEV box of each box.
...@@ -99,7 +99,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes): ...@@ -99,7 +99,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes):
@property @property
def nearest_bev(self): def nearest_bev(self):
"""Calculate the 2D bounding boxes in BEV without rotation """Calculate the 2D bounding boxes in BEV without rotation.
Returns: Returns:
torch.Tensor: A tensor of 2D BEV box of each box. torch.Tensor: A tensor of 2D BEV box of each box.
...@@ -159,7 +159,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes): ...@@ -159,7 +159,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes):
return points, rot_mat_T return points, rot_mat_T
def flip(self, bev_direction='horizontal', points=None): def flip(self, bev_direction='horizontal', points=None):
"""Flip the boxes in BEV along given BEV direction """Flip the boxes in BEV along given BEV direction.
In LIDAR coordinates, it flips the y (horizontal) or x (vertical) axis. In LIDAR coordinates, it flips the y (horizontal) or x (vertical) axis.
...@@ -190,7 +190,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes): ...@@ -190,7 +190,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes):
return points return points
def in_range_bev(self, box_range): def in_range_bev(self, box_range):
"""Check whether the boxes are in the given range """Check whether the boxes are in the given range.
Args: Args:
box_range (list | torch.Tensor): the range of box box_range (list | torch.Tensor): the range of box
...@@ -232,7 +232,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes): ...@@ -232,7 +232,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes):
box=self, src=Box3DMode.LIDAR, dst=dst, rt_mat=rt_mat) box=self, src=Box3DMode.LIDAR, dst=dst, rt_mat=rt_mat)
def enlarged_box(self, extra_width): def enlarged_box(self, extra_width):
"""Enlarge the length, width and height boxes """Enlarge the length, width and height boxes.
Args: Args:
extra_width (float | torch.Tensor): extra width to enlarge the box extra_width (float | torch.Tensor): extra width to enlarge the box
......
...@@ -19,7 +19,7 @@ def limit_period(val, offset=0.5, period=np.pi): ...@@ -19,7 +19,7 @@ def limit_period(val, offset=0.5, period=np.pi):
def rotation_3d_in_axis(points, angles, axis=0): def rotation_3d_in_axis(points, angles, axis=0):
"""Rotate points by angles according to axis """Rotate points by angles according to axis.
Args: Args:
points (torch.Tensor): Points of shape (N, M, 3). points (torch.Tensor): Points of shape (N, M, 3).
...@@ -92,8 +92,8 @@ def get_box_type(box_type): ...@@ -92,8 +92,8 @@ def get_box_type(box_type):
Returns: Returns:
tuple: box type and box mode. tuple: box type and box mode.
""" """
from .box_3d_mode import (LiDARInstance3DBoxes, CameraInstance3DBoxes, from .box_3d_mode import (Box3DMode, CameraInstance3DBoxes,
DepthInstance3DBoxes, Box3DMode) DepthInstance3DBoxes, LiDARInstance3DBoxes)
box_type_lower = box_type.lower() box_type_lower = box_type.lower()
if box_type_lower == 'lidar': if box_type_lower == 'lidar':
box_type_3d = LiDARInstance3DBoxes box_type_3d = LiDARInstance3DBoxes
...@@ -112,7 +112,7 @@ def get_box_type(box_type): ...@@ -112,7 +112,7 @@ def get_box_type(box_type):
def points_cam2img(points_3d, proj_mat): def points_cam2img(points_3d, proj_mat):
"""Project points from camera coordicates to image coordinates """Project points from camera coordicates to image coordinates.
Args: Args:
points_3d (torch.Tensor): Points in shape (N, 3) points_3d (torch.Tensor): Points in shape (N, 3)
......
...@@ -2,7 +2,7 @@ import torch ...@@ -2,7 +2,7 @@ import torch
def bbox3d_mapping_back(bboxes, scale_factor, flip_horizontal, flip_vertical): def bbox3d_mapping_back(bboxes, scale_factor, flip_horizontal, flip_vertical):
"""Map bboxes from testing scale to original image scale""" """Map bboxes from testing scale to original image scale."""
new_bboxes = bboxes.clone() new_bboxes = bboxes.clone()
if flip_horizontal: if flip_horizontal:
new_bboxes.flip('horizontal') new_bboxes.flip('horizontal')
......
...@@ -51,8 +51,8 @@ def average_precision(recalls, precisions, mode='area'): ...@@ -51,8 +51,8 @@ def average_precision(recalls, precisions, mode='area'):
def eval_det_cls(pred, gt, iou_thr=None): def eval_det_cls(pred, gt, iou_thr=None):
"""Generic functions to compute precision/recall for object detection """Generic functions to compute precision/recall for object detection for a
for a single class. single class.
Args: Args:
pred (dict): {img_id: [(bbox, score)]} where bbox is numpy array. pred (dict): {img_id: [(bbox, score)]} where bbox is numpy array.
......
import gc import gc
import io as sysio import io as sysio
import numba import numba
import numpy as np import numpy as np
...@@ -340,8 +339,8 @@ def fused_compute_statistics(overlaps, ...@@ -340,8 +339,8 @@ def fused_compute_statistics(overlaps,
def calculate_iou_partly(gt_annos, dt_annos, metric, num_parts=50): def calculate_iou_partly(gt_annos, dt_annos, metric, num_parts=50):
"""Fast iou algorithm. this function can be used independently to """Fast iou algorithm. this function can be used independently to do result
do result analysis. Must be used in CAMERA coordinate system. analysis. Must be used in CAMERA coordinate system.
Args: Args:
gt_annos (dict): Must from get_label_annos() in kitti_common.py. gt_annos (dict): Must from get_label_annos() in kitti_common.py.
...@@ -487,7 +486,7 @@ def eval_class(gt_annos, ...@@ -487,7 +486,7 @@ def eval_class(gt_annos,
[num_class, num_difficulty, num_minoverlap, N_SAMPLE_PTS]) [num_class, num_difficulty, num_minoverlap, N_SAMPLE_PTS])
aos = np.zeros([num_class, num_difficulty, num_minoverlap, N_SAMPLE_PTS]) aos = np.zeros([num_class, num_difficulty, num_minoverlap, N_SAMPLE_PTS])
for m, current_class in enumerate(current_classes): for m, current_class in enumerate(current_classes):
for l, difficulty in enumerate(difficultys): for idx_l, difficulty in enumerate(difficultys):
rets = _prepare_data(gt_annos, dt_annos, current_class, difficulty) rets = _prepare_data(gt_annos, dt_annos, current_class, difficulty)
(gt_datas_list, dt_datas_list, ignored_gts, ignored_dets, (gt_datas_list, dt_datas_list, ignored_gts, ignored_dets,
dontcares, total_dc_num, total_num_valid_gt) = rets dontcares, total_dc_num, total_num_valid_gt) = rets
...@@ -540,16 +539,19 @@ def eval_class(gt_annos, ...@@ -540,16 +539,19 @@ def eval_class(gt_annos,
compute_aos=compute_aos) compute_aos=compute_aos)
idx += num_part idx += num_part
for i in range(len(thresholds)): for i in range(len(thresholds)):
recall[m, l, k, i] = pr[i, 0] / (pr[i, 0] + pr[i, 2]) recall[m, idx_l, k, i] = pr[i, 0] / (pr[i, 0] + pr[i, 2])
precision[m, l, k, i] = pr[i, 0] / (pr[i, 0] + pr[i, 1]) precision[m, idx_l, k, i] = pr[i, 0] / (
pr[i, 0] + pr[i, 1])
if compute_aos: if compute_aos:
aos[m, l, k, i] = pr[i, 3] / (pr[i, 0] + pr[i, 1]) aos[m, idx_l, k, i] = pr[i, 3] / (pr[i, 0] + pr[i, 1])
for i in range(len(thresholds)): for i in range(len(thresholds)):
precision[m, l, k, i] = np.max( precision[m, idx_l, k, i] = np.max(
precision[m, l, k, i:], axis=-1) precision[m, idx_l, k, i:], axis=-1)
recall[m, l, k, i] = np.max(recall[m, l, k, i:], axis=-1) recall[m, idx_l, k, i] = np.max(
recall[m, idx_l, k, i:], axis=-1)
if compute_aos: if compute_aos:
aos[m, l, k, i] = np.max(aos[m, l, k, i:], axis=-1) aos[m, idx_l, k, i] = np.max(
aos[m, idx_l, k, i:], axis=-1)
ret_dict = { ret_dict = {
'recall': recall, 'recall': recall,
'precision': precision, 'precision': precision,
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
# Author: yanyan, scrin@foxmail.com # Author: yanyan, scrin@foxmail.com
##################### #####################
import math import math
import numba import numba
import numpy as np import numpy as np
from numba import cuda from numba import cuda
...@@ -304,10 +303,9 @@ def rotate_iou_kernel_eval(N, ...@@ -304,10 +303,9 @@ def rotate_iou_kernel_eval(N,
def rotate_iou_gpu_eval(boxes, query_boxes, criterion=-1, device_id=0): def rotate_iou_gpu_eval(boxes, query_boxes, criterion=-1, device_id=0):
"""Rotated box iou running in gpu. 500x faster than cpu version """Rotated box iou running in gpu. 500x faster than cpu version (take 5ms
(take 5ms in one example with numba.cuda code). in one example with numba.cuda code). convert from [this project](
convert from [this project]( https://github.com/hongzhenwang/RRPN-revise/tree/master/lib/rotation).
https://github.com/hongzhenwang/RRPN-revise/tree/master/lib/rotation).
Args: Args:
boxes (torch.Tensor): rbboxes. format: centers, dims, boxes (torch.Tensor): rbboxes. format: centers, dims,
......
import os.path as osp
import mmcv import mmcv
import numpy as np import numpy as np
from lyft_dataset_sdk.eval.detection.mAP_evaluation import (Box3D, get_ap, from lyft_dataset_sdk.eval.detection.mAP_evaluation import (Box3D, get_ap,
...@@ -8,6 +6,7 @@ from lyft_dataset_sdk.eval.detection.mAP_evaluation import (Box3D, get_ap, ...@@ -8,6 +6,7 @@ from lyft_dataset_sdk.eval.detection.mAP_evaluation import (Box3D, get_ap,
group_by_key, group_by_key,
wrap_in_box) wrap_in_box)
from mmcv.utils import print_log from mmcv.utils import print_log
from os import path as osp
from terminaltables import AsciiTable from terminaltables import AsciiTable
...@@ -198,8 +197,8 @@ def get_classwise_aps(gt: list, predictions: list, class_names: list, ...@@ -198,8 +197,8 @@ def get_classwise_aps(gt: list, predictions: list, class_names: list,
def get_single_class_aps(gt, predictions, iou_thresholds): def get_single_class_aps(gt, predictions, iou_thresholds):
"""Compute recall and precision for all iou thresholds. """Compute recall and precision for all iou thresholds. Adapted from
Adapted from LyftDatasetDevkit. LyftDatasetDevkit.
Args: Args:
gt (list[dict]): list of dictionaries in the format described above. gt (list[dict]): list of dictionaries in the format described above.
......
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