Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
mmdetection3d
Commits
8f88914d
Commit
8f88914d
authored
Jun 20, 2020
by
liyinhao
Committed by
zhangwenwei
Jun 20, 2020
Browse files
Add docstrings
parent
613c8844
Changes
31
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
310 additions
and
260 deletions
+310
-260
data/scannet/load_scannet_data.py
data/scannet/load_scannet_data.py
+10
-10
data/sunrgbd/sunrgbd_utils.py
data/sunrgbd/sunrgbd_utils.py
+19
-19
mmdet3d/core/anchor/anchor_3d_generator.py
mmdet3d/core/anchor/anchor_3d_generator.py
+1
-1
mmdet3d/core/bbox/box_np_ops.py
mmdet3d/core/bbox/box_np_ops.py
+64
-51
mmdet3d/core/bbox/box_torch_ops.py
mmdet3d/core/bbox/box_torch_ops.py
+28
-23
mmdet3d/core/bbox/coders/delta_xyzwhlr_bbox_coder.py
mmdet3d/core/bbox/coders/delta_xyzwhlr_bbox_coder.py
+31
-18
mmdet3d/core/bbox/coders/partial_bin_based_bbox_coder.py
mmdet3d/core/bbox/coders/partial_bin_based_bbox_coder.py
+10
-11
mmdet3d/core/bbox/iou_calculators/iou3d_calculator.py
mmdet3d/core/bbox/iou_calculators/iou3d_calculator.py
+11
-9
mmdet3d/core/bbox/samplers/iou_neg_piecewise_sampler.py
mmdet3d/core/bbox/samplers/iou_neg_piecewise_sampler.py
+1
-1
mmdet3d/core/bbox/structures/base_box3d.py
mmdet3d/core/bbox/structures/base_box3d.py
+17
-17
mmdet3d/core/bbox/structures/box_3d_mode.py
mmdet3d/core/bbox/structures/box_3d_mode.py
+6
-6
mmdet3d/core/bbox/structures/cam_box3d.py
mmdet3d/core/bbox/structures/cam_box3d.py
+19
-19
mmdet3d/core/bbox/structures/depth_box3d.py
mmdet3d/core/bbox/structures/depth_box3d.py
+14
-14
mmdet3d/core/bbox/structures/lidar_box3d.py
mmdet3d/core/bbox/structures/lidar_box3d.py
+6
-6
mmdet3d/core/bbox/structures/utils.py
mmdet3d/core/bbox/structures/utils.py
+1
-1
mmdet3d/core/bbox/transforms.py
mmdet3d/core/bbox/transforms.py
+39
-23
mmdet3d/core/evaluation/indoor_eval.py
mmdet3d/core/evaluation/indoor_eval.py
+9
-10
mmdet3d/core/evaluation/kitti_utils/eval.py
mmdet3d/core/evaluation/kitti_utils/eval.py
+16
-13
mmdet3d/core/evaluation/kitti_utils/rotate_iou.py
mmdet3d/core/evaluation/kitti_utils/rotate_iou.py
+4
-4
mmdet3d/core/post_processing/box3d_nms.py
mmdet3d/core/post_processing/box3d_nms.py
+4
-4
No files found.
data/scannet/load_scannet_data.py
View file @
8f88914d
...
...
@@ -64,19 +64,19 @@ def export(mesh_file,
"""Export original files to vert, ins_label, sem_label and bbox file.
Args:
mesh_file(str): Path of the mesh_file.
agg_file(str): Path of the agg_file.
seg_file(str): Path of the seg_file.
meta_file(str): Path of the meta_file.
label_map_file(str): Path of the label_map_file.
output_file(str): Path of the output folder.
mesh_file
(str): Path of the mesh_file.
agg_file
(str): Path of the agg_file.
seg_file
(str): Path of the seg_file.
meta_file
(str): Path of the meta_file.
label_map_file
(str): Path of the label_map_file.
output_file
(str): Path of the output folder.
Default: None.
It returns a tuple, which containts the the following things:
ndarray: Vertices of points data.
ndarray: Indexes of label.
ndarray: Indexes of instance.
ndarray: Instance bboxes.
np.
ndarray: Vertices of points data.
np.
ndarray: Indexes of label.
np.
ndarray: Indexes of instance.
np.
ndarray: Instance bboxes.
dict: Map from object_id to label_id.
"""
...
...
data/sunrgbd/sunrgbd_utils.py
View file @
8f88914d
...
...
@@ -39,10 +39,10 @@ def flip_axis_to_camera(pc):
Flip X-right,Y-forward,Z-up to X-right,Y-down,Z-forward.
Args:
pc
(
ndarray): points in depth axis.
pc
(np.
ndarray): points in depth axis.
Returns:
ndarray: points in camera axis.
np.
ndarray: points in camera axis.
"""
pc2
=
np
.
copy
(
pc
)
pc2
[:,
[
0
,
1
,
2
]]
=
pc2
[:,
[
0
,
2
,
1
]]
# cam X,Y,Z = depth X,-Z,Y
...
...
@@ -132,10 +132,10 @@ class SUNRGBD_Calibration(object):
"""Convert pc coordinate from depth to image.
Args:
pc
(
ndarray): Point cloud in depth coordinate.
pc
(np.
ndarray): Point cloud in depth coordinate.
Returns:
pc
(
ndarray): Point cloud in camera coordinate.
pc
(np.
ndarray): Point cloud in camera coordinate.
"""
# Project upright depth to depth coordinate
pc2
=
np
.
dot
(
np
.
transpose
(
self
.
Rtilt
),
np
.
transpose
(
pc
[:,
...
...
@@ -146,11 +146,11 @@ class SUNRGBD_Calibration(object):
"""Convert pc coordinate from depth to image.
Args:
pc
(
ndarray): Point cloud in depth coordinate.
pc
(np.
ndarray): Point cloud in depth coordinate.
Returns:
ndarray: [N, 2] uv.
ndarray: [n,] depth.
np.
ndarray: [N, 2] uv.
np.
ndarray: [n,] depth.
"""
pc2
=
self
.
project_upright_depth_to_camera
(
pc
)
uv
=
np
.
dot
(
pc2
,
np
.
transpose
(
self
.
K
))
# (n,3)
...
...
@@ -173,10 +173,10 @@ def rotz(t):
"""Rotation about the z-axis.
Args:
t(float): Heading angle.
t
(float): Heading angle.
Returns:
ndarray: Transforation matrix
np.
ndarray: Transforation matrix
"""
c
=
np
.
cos
(
t
)
s
=
np
.
sin
(
t
)
...
...
@@ -187,11 +187,11 @@ def transform_from_rot_trans(R, t):
"""Transforation matrix from rotation matrix and translation vector.
Args:
R
(
ndarray): Rotation matrix.
t
(
ndarray): Translation vector.
R
(np.
ndarray): Rotation matrix.
t
(np.
ndarray): Translation vector.
Returns:
ndarray: Transforation matrix.
np.
ndarray: Transforation matrix.
"""
R
=
R
.
reshape
(
3
,
3
)
t
=
t
.
reshape
(
3
,
1
)
...
...
@@ -229,12 +229,12 @@ def extract_pc_in_box3d(pc, box3d):
"""Extract point cloud in box3d.
Args:
pc
(
ndarray): [N, 3] Point cloud.
box3d
(
ndarray): [8,3] 3d box.
pc
(np.
ndarray): [N, 3] Point cloud.
box3d
(np.
ndarray): [8,3] 3d box.
Returns:
ndarray: Selected point cloud.
ndarray: Indices of selected point cloud.
np.
ndarray: Selected point cloud.
np.
ndarray: Indices of selected point cloud.
"""
box3d_roi_inds
=
in_hull
(
pc
[:,
0
:
3
],
box3d
)
return
pc
[
box3d_roi_inds
,
:],
box3d_roi_inds
...
...
@@ -258,11 +258,11 @@ def compute_box_3d(obj, calib):
bounding box into the image plane.
Args:
obj(SUNObject3d): Instance of SUNObject3d.
calib(SUNRGBD_Calibration): Instance of SUNRGBD_Calibration.
obj
(SUNObject3d): Instance of SUNObject3d.
calib
(SUNRGBD_Calibration): Instance of SUNRGBD_Calibration.
Returns:
ndarray: [8,2] array in image coord.
np.
ndarray: [8,2] array in image coord.
corners_3d: [8,3] array in in upright depth coord.
"""
center
=
obj
.
centroid
...
...
mmdet3d/core/anchor/anchor_3d_generator.py
View file @
8f88914d
...
...
@@ -85,7 +85,7 @@ class Anchor3DRangeGenerator(object):
multiple feature levels.
device (str): Device where the anchors will be put on.
Return:
Return
s
:
list[torch.Tensor]: Anchors in multiple feature levels.
The sizes of each tensor should be [N, 4], where
N = width * height * num_base_anchors, width and height
...
...
mmdet3d/core/bbox/box_np_ops.py
View file @
8f88914d
...
...
@@ -19,18 +19,18 @@ def box_camera_to_lidar(data, r_rect, velo2cam):
def
corners_nd
(
dims
,
origin
=
0.5
):
"""
g
enerate relative box corners based on length per dim and
"""
G
enerate relative box corners based on length per dim and
origin point.
Args:
dims (
float
array, shape=[N, ndim]):
a
rray of length per dim
dims (
np.nd
array, shape=[N, ndim]):
A
rray of length per dim
origin (list or array or float): origin point relate to smallest point.
Returns:
float
array, shape=[N, 2 ** ndim, ndim]:
r
eturned corners.
np.nd
array, shape=[N, 2 ** ndim, ndim]:
R
eturned corners.
point layout example: (2d) x0y0, x0y1, x1y0, x1y1;
(3d) x0y0z0, x0y0z1, x0y1z0, x0y1z1, x1y0z0, x1y0z1, x1y1z0, x1y1z1
where x0 < x1, y0 < y1, z0 < z1
where x0 < x1, y0 < y1, z0 < z1
.
"""
ndim
=
int
(
dims
.
shape
[
1
])
corners_norm
=
np
.
stack
(
...
...
@@ -53,14 +53,14 @@ def corners_nd(dims, origin=0.5):
def
rotation_2d
(
points
,
angles
):
"""
r
otation 2d points based on origin point clockwise when angle positive.
"""
R
otation 2d points based on origin point clockwise when angle positive.
Args:
points (
float
array, shape=[N, point_size, 2]): points to be rotated.
angles (
float
array, shape=[N]): rotation angle.
points (
np.nd
array, shape=[N, point_size, 2]): points to be rotated.
angles (
np.nd
array, shape=[N]): rotation angle.
Returns:
float
array:
s
ame shape as points
np.nd
array:
S
ame shape as points
.
"""
rot_sin
=
np
.
sin
(
angles
)
rot_cos
=
np
.
cos
(
angles
)
...
...
@@ -69,16 +69,16 @@ def rotation_2d(points, angles):
def
center_to_corner_box2d
(
centers
,
dims
,
angles
=
None
,
origin
=
0.5
):
"""
c
onvert kitti locations, dimensions and angles to corners.
"""
C
onvert kitti locations, dimensions and angles to corners.
format: center(xy), dims(xy), angles(clockwise when positive)
Args:
centers (
float
array, shape=[N, 2]): locations in kitti label file.
dims (
float
array, shape=[N, 2]): dimensions in kitti label file.
angles (
float
array, shape=[N]): rotation_y in kitti label file.
centers (
np.nd
array, shape=[N, 2]): locations in kitti label file.
dims (
np.nd
array, shape=[N, 2]): dimensions in kitti label file.
angles (
np.nd
array, shape=[N]): rotation_y in kitti label file.
Returns:
[type]: [description]
np.ndarray: Corners with the shape of [N, 4, 2].
"""
# 'length' in kitti format is in x axis.
# xyz(hwl)(kitti label file)<->xyz(lhw)(camera)<->z(-x)(-y)(wlh)(lidar)
...
...
@@ -141,17 +141,18 @@ def center_to_corner_box3d(centers,
angles
=
None
,
origin
=
(
0.5
,
1.0
,
0.5
),
axis
=
1
):
"""
c
onvert kitti locations, dimensions and angles to corners
"""
C
onvert kitti locations, dimensions and angles to corners
.
Args:
centers (
float
array, shape=[N, 3]):
l
ocations in kitti label file.
dims (
float
array, shape=[N, 3]):
d
imensions in kitti label file.
angles (
float
array, shape=[N]):
r
otation_y in kitti label file.
origin (list or array or float):
o
rigin point relate to smallest point.
centers (
np.nd
array, shape=[N, 3]):
L
ocations in kitti label file.
dims (
np.nd
array, shape=[N, 3]):
D
imensions in kitti label file.
angles (
np.nd
array, shape=[N]):
R
otation_y in kitti label file.
origin (list or array or float):
O
rigin point relate to smallest point.
use (0.5, 1.0, 0.5) in camera and (0.5, 0.5, 0) in lidar.
axis (int): rotation axis. 1 for camera and 2 for lidar.
axis (int): Rotation axis. 1 for camera and 2 for lidar.
Returns:
[type]: [description]
np.ndarray: Corners with the shape of [N, 8, 3].
"""
# 'length' in kitti format is in x axis.
# yzx(hwl)(kitti label file)<->xyz(lhw)(camera)<->z(-x)(-y)(wlh)(lidar)
...
...
@@ -202,13 +203,15 @@ def corner_to_standup_nd_jit(boxes_corner):
@
numba
.
jit
(
nopython
=
True
)
def
corner_to_surfaces_3d_jit
(
corners
):
"""
c
onvert 3d box corners from corner function above
"""
C
onvert 3d box corners from corner function above
to surfaces that normal vectors all direct to internal.
Args:
corners (float array, [N, 8, 3]): 3d box corners.
corners (np.ndarray, [N, 8, 3]): 3d box corners
with the shape of [N, 8, 3].
Returns:
surfaces (float array,
[N, 6, 4, 3]
):
np.ndarray: Surfaces with the shape of
[N, 6, 4, 3]
.
"""
# box_corners: [N, 8, 3], must from corner functions in this module
num_boxes
=
corners
.
shape
[
0
]
...
...
@@ -270,9 +273,10 @@ def corner_to_surfaces_3d(corners):
to surfaces that normal vectors all direct to internal.
Args:
corners (float array, [N, 8, 3]): 3d box corners.
corners (np.ndarray, [N, 8, 3]): 3d box corners.
Returns:
surfaces (float array,
[N, 6, 4, 3]
):
np.ndarray: Surfaces with the shape of
[N, 6, 4, 3]
.
"""
# box_corners: [N, 8, 3], must from corner functions in this module
surfaces
=
np
.
array
([
...
...
@@ -318,7 +322,7 @@ def create_anchors_3d_range(feature_size,
sizes: [N, 3] list of list or array, size of anchors, xyz
Returns:
anchors
: [*feature_size, num_sizes, num_rots, 7]
tensor
.
np.ndarray
: [*feature_size, num_sizes, num_rots, 7].
"""
anchor_range
=
np
.
array
(
anchor_range
,
dtype
)
z_centers
=
np
.
linspace
(
...
...
@@ -358,10 +362,13 @@ def center_to_minmax_2d(centers, dims, origin=0.5):
def
rbbox2d_to_near_bbox
(
rbboxes
):
"""convert rotated bbox to nearest 'standing' or 'lying' bbox.
Args:
rbboxes: [N, 5(x, y, xdim, ydim, rad)] rotated bboxes
rbboxes (np.ndarray): [N, 5(x, y, xdim, ydim, rad)] rotated bboxes.
Returns:
bboxes: [N, 4(xmin, ymin, xmax, ymax)] bboxes
np.ndarray: Bboxes with the shpae of
[N, 4(xmin, ymin, xmax, ymax)].
"""
rots
=
rbboxes
[...,
-
1
]
rots_0_pi_div_2
=
np
.
abs
(
limit_period
(
rots
,
0.5
,
np
.
pi
))
...
...
@@ -373,15 +380,16 @@ def rbbox2d_to_near_bbox(rbboxes):
@
numba
.
jit
(
nopython
=
True
)
def
iou_jit
(
boxes
,
query_boxes
,
mode
=
'iou'
,
eps
=
0.0
):
"""calculate box iou. note that jit version runs ~10x faster than the
box_overlaps function in mmdet3d.core.evaluation
Parameters
----------
boxes: (N, 4) ndarray of float
query_boxes: (K, 4) ndarray of float
Returns
-------
overlaps: (N, K) ndarray of overlap between boxes and query_boxes
"""Calculate box iou. note that jit version runs ~10x faster than the
box_overlaps function in mmdet3d.core.evaluation.
Args:
boxes (np.ndarray): (N, 4) ndarray of float
query_boxes (np.ndarray): (K, 4) ndarray of float
Returns:
np.ndarray: Overlap between boxes and query_boxes
with the shape of [N, K].
"""
N
=
boxes
.
shape
[
0
]
K
=
query_boxes
.
shape
[
0
]
...
...
@@ -502,17 +510,19 @@ def _points_in_convex_polygon_3d_jit(points, polygon_surfaces, normal_vec, d,
def
points_in_convex_polygon_3d_jit
(
points
,
polygon_surfaces
,
num_surfaces
=
None
):
"""check points is in 3d convex polygons.
"""Check points is in 3d convex polygons.
Args:
points: [num_points, 3] array.
polygon_surfaces: [num_polygon, max_num_surfaces,
points
(np.ndarray)
: [num_points, 3] array.
polygon_surfaces
(np.ndarray)
: [num_polygon, max_num_surfaces,
max_num_points_of_surface, 3]
array. all surfaces' normal vector must direct to internal.
max_num_points_of_surface must at least 3.
num_surfaces: [num_polygon] array. indicate how many surfaces
a polygon contain
num_surfaces (np.ndarray): [num_polygon] array.
indicate how many surfaces a polygon contain
Returns:
[num_points, num_polygon]
bool array
.
np.ndarray: Result matrix with the shape of
[num_points, num_polygon].
"""
max_num_surfaces
,
max_num_points_of_surface
=
polygon_surfaces
.
shape
[
1
:
3
]
# num_points = points.shape[0]
...
...
@@ -528,13 +538,16 @@ def points_in_convex_polygon_3d_jit(points,
@
numba
.
jit
def
points_in_convex_polygon_jit
(
points
,
polygon
,
clockwise
=
True
):
"""check points is in 2d convex polygons. True when point in polygon
"""Check points is in 2d convex polygons. True when point in polygon.
Args:
points: [num_points, 2] array.
polygon: [num_polygon, num_points_of_polygon, 2] array.
clockwise: bool. indicate polygon is clockwise.
points (np.ndarray): Input points with the shape of [num_points, 2].
polygon (dnarray): Input polygon with the shape of
[num_polygon, num_points_of_polygon, 2].
clockwise (bool): Indicate polygon is clockwise.
Returns:
[num_points, num_polygon]
bool array
.
np.ndarray: Result matrix with the shape of
[num_points, num_polygon].
"""
# first convert polygon to directed lines
num_points_of_polygon
=
polygon
.
shape
[
1
]
...
...
@@ -569,7 +582,7 @@ def points_in_convex_polygon_jit(points, polygon, clockwise=True):
def
boxes3d_to_corners3d_lidar
(
boxes3d
,
bottom_center
=
True
):
"""
c
onvert kitti center boxes to corners
"""
C
onvert kitti center boxes to corners
.
7 -------- 4
/| /|
...
...
@@ -580,12 +593,12 @@ def boxes3d_to_corners3d_lidar(boxes3d, bottom_center=True):
2 -------- 1
Args:
boxes3d (n
umpy.
array): (N, 7) [x, y, z, w, l, h, ry] in LiDAR coords,
boxes3d (n
p.nd
array): (N, 7) [x, y, z, w, l, h, ry] in LiDAR coords,
see the definition of ry in KITTI dataset
bottom_center (bool): whether z is on the bottom center of object.
Returns:
n
umpy.
array:
b
ox corners with shape
(
N, 8, 3
)
n
p.nd
array:
B
ox corners with
the
shape
of [
N, 8, 3
].
"""
boxes_num
=
boxes3d
.
shape
[
0
]
w
,
l
,
h
=
boxes3d
[:,
3
],
boxes3d
[:,
4
],
boxes3d
[:,
5
]
...
...
mmdet3d/core/bbox/box_torch_ops.py
View file @
8f88914d
...
...
@@ -7,15 +7,15 @@ def limit_period(val, offset=0.5, period=np.pi):
def
corners_nd
(
dims
,
origin
=
0.5
):
"""
g
enerate relative box corners based on length per dim and
"""
G
enerate relative box corners based on length per dim and
origin point.
Args:
dims (
float
array, shape=[N, ndim]):
a
rray of length per dim
origin (list or array or float):
o
rigin point relate to smallest point.
dims (
np.nd
array, shape=[N, ndim]):
A
rray of length per dim
origin (list or array or float):
O
rigin point relate to smallest point.
Returns:
float array,
shape
=
[N, 2 ** ndim, ndim]
: returned corners
.
np.ndarray: Corners of boxes in
shape
[N, 2 ** ndim, ndim].
point layout example: (2d) x0y0, x0y1, x1y0, x1y1;
(3d) x0y0z0, x0y0z1, x0y1z0, x0y1z1, x1y0z0, x1y0z1, x1y1z0, x1y1z1
where x0 < x1, y0 < y1, z0 < z1
...
...
@@ -76,17 +76,21 @@ def center_to_corner_box3d(centers,
angles
,
origin
=
(
0.5
,
1.0
,
0.5
),
axis
=
1
):
"""
c
onvert kitti locations, dimensions and angles to corners
"""
C
onvert kitti locations, dimensions and angles to corners
.
Args:
centers (float array, shape=[N, 3]): locations in kitti label file.
dims (float array, shape=[N, 3]): dimensions in kitti label file.
angles (float array, shape=[N]): rotation_y in kitti label file.
origin (list or array or float): origin point relate to smallest point.
centers (np.ndarray): Locations in kitti label file
with the shape of [N, 3].
dims (np.ndarray): Dimensions in kitti label
file with the shape of [N, 3]
angles (np.ndarray): Rotation_y in kitti
label file with the shape of [N]
origin (list or array or float): Origin point relate to smallest point.
use (0.5, 1.0, 0.5) in camera and (0.5, 0.5, 0) in lidar.
axis (int): rotation axis. 1 for camera and 2 for lidar.
axis (int): Rotation axis. 1 for camera and 2 for lidar.
Returns:
[type]: [description]
torch.Tensor: Corners with the shape of [N, 8, 3].
"""
# 'length' in kitti format is in x axis.
# yzx(hwl)(kitti label file)<->xyz(lhw)(camera)<->z(-x)(-y)(wlh)(lidar)
...
...
@@ -130,9 +134,10 @@ def rbbox2d_to_near_bbox(rbboxes):
"""convert rotated bbox to nearest 'standing' or 'lying' bbox.
Args:
rbboxes: [N, 5(x, y, xdim, ydim, rad)] rotated bboxes
rbboxes (torch.Tensor): [N, 5(x, y, xdim, ydim, rad)] rotated bboxes.
Returns:
bboxes:
[N, 4(xmin, ymin, xmax, ymax)]
bboxes
torch.Tensor: Bboxes with the shape of
[N, 4(xmin, ymin, xmax, ymax)]
.
"""
rots
=
rbboxes
[...,
-
1
]
rots_0_pi_div_2
=
torch
.
abs
(
limit_period
(
rots
,
0.5
,
np
.
pi
))
...
...
@@ -154,16 +159,16 @@ def center_to_minmax_2d(centers, dims, origin=0.5):
def
center_to_corner_box2d
(
centers
,
dims
,
angles
=
None
,
origin
=
0.5
):
"""
c
onvert kitti locations, dimensions and angles to corners.
"""
C
onvert kitti locations, dimensions and angles to corners.
format: center(xy), dims(xy), angles(clockwise when positive)
Args:
centers (
float
array, shape=[N, 2]): locations in kitti label file.
dims (
float
array, shape=[N, 2]): dimensions in kitti label file.
angles (
float
array, shape=[N]): rotation_y in kitti label file.
centers (
np.nd
array, shape=[N, 2]): locations in kitti label file.
dims (
np.nd
array, shape=[N, 2]): dimensions in kitti label file.
angles (
np.nd
array, shape=[N]): rotation_y in kitti label file.
Returns:
[type]: [description]
torch.Tensor: Corners with the shape of [N, 4, 2].
"""
# 'length' in kitti format is in x axis.
# xyz(hwl)(kitti label file)<->xyz(lhw)(camera)<->z(-x)(-y)(wlh)(lidar)
...
...
@@ -180,11 +185,11 @@ def rotation_2d(points, angles):
"""rotation 2d points based on origin point clockwise when angle positive.
Args:
points (
float
array, shape=[N, point_size, 2]): points to be rotated.
angles (
float
array, shape=[N]): rotation angle.
points (
np.nd
array, shape=[N, point_size, 2]): points to be rotated.
angles (
np.nd
array, shape=[N]): rotation angle.
Returns:
float
array:
s
ame shape as points
np.nd
array:
S
ame shape as points
.
"""
rot_sin
=
torch
.
sin
(
angles
)
rot_cos
=
torch
.
cos
(
angles
)
...
...
@@ -213,7 +218,7 @@ def enlarge_box3d_lidar(boxes3d, extra_width):
def
boxes3d_to_corners3d_lidar_torch
(
boxes3d
,
bottom_center
=
True
):
"""
c
onvert kitti center boxes to corners
"""
C
onvert kitti center boxes to corners
.
7 -------- 4
/| /|
...
...
mmdet3d/core/bbox/coders/delta_xyzwhlr_bbox_coder.py
View file @
8f88914d
...
...
@@ -12,21 +12,30 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder):
self
.
code_size
=
code_size
@
staticmethod
def
encode
(
anchors
,
boxes
):
"""
:param boxes: (N, 7+n) x, y, z, w, l, h, r, velo*
:param anchors: (N, 7+n)
:return:
def
encode
(
src_boxes
,
dst_boxes
):
"""Get box regression transformation deltas
(dx, dy, dz, dw, dh, dl, dr, dv*) that can be used
to transform the `src_boxes` into the `target_boxes`.
Args:
src_boxes (torch.Tensor): source boxes, e.g., object proposals.
dst_boxes (torch.Tensor): target of the transformation, e.g.,
ground-truth boxes.
Returns:
torch.Tensor: Box transformation deltas
"""
box_ndim
=
anchor
s
.
shape
[
-
1
]
box_ndim
=
src_boxe
s
.
shape
[
-
1
]
cas
,
cgs
,
cts
=
[],
[],
[]
if
box_ndim
>
7
:
xa
,
ya
,
za
,
wa
,
la
,
ha
,
ra
,
*
cas
=
torch
.
split
(
anchors
,
1
,
dim
=-
1
)
xg
,
yg
,
zg
,
wg
,
lg
,
hg
,
rg
,
*
cgs
=
torch
.
split
(
boxes
,
1
,
dim
=-
1
)
xa
,
ya
,
za
,
wa
,
la
,
ha
,
ra
,
*
cas
=
torch
.
split
(
src_boxes
,
1
,
dim
=-
1
)
xg
,
yg
,
zg
,
wg
,
lg
,
hg
,
rg
,
*
cgs
=
torch
.
split
(
dst_boxes
,
1
,
dim
=-
1
)
cts
=
[
g
-
a
for
g
,
a
in
zip
(
cgs
,
cas
)]
else
:
xa
,
ya
,
za
,
wa
,
la
,
ha
,
ra
=
torch
.
split
(
anchor
s
,
1
,
dim
=-
1
)
xg
,
yg
,
zg
,
wg
,
lg
,
hg
,
rg
=
torch
.
split
(
boxes
,
1
,
dim
=-
1
)
xa
,
ya
,
za
,
wa
,
la
,
ha
,
ra
=
torch
.
split
(
src_boxe
s
,
1
,
dim
=-
1
)
xg
,
yg
,
zg
,
wg
,
lg
,
hg
,
rg
=
torch
.
split
(
dst_
boxes
,
1
,
dim
=-
1
)
za
=
za
+
ha
/
2
zg
=
zg
+
hg
/
2
diagonal
=
torch
.
sqrt
(
la
**
2
+
wa
**
2
)
...
...
@@ -40,21 +49,25 @@ class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder):
return
torch
.
cat
([
xt
,
yt
,
zt
,
wt
,
lt
,
ht
,
rt
,
*
cts
],
dim
=-
1
)
@
staticmethod
def
decode
(
anchors
,
box_encodings
):
"""
:param box_encodings: (N, 7 + n) x, y, z, w, l, h, r
:param anchors: (N, 7)
:return:
def
decode
(
anchors
,
deltas
):
"""Apply transformation `deltas` (dx, dy, dz, dw, dh, dl, dr, dv*) to `boxes`.
Args:
anchors (torch.Tensor): Parameters of anchors with shape (N, 7).
deltas (torch.Tensor): Encoded boxes with shape
(N, 7+n) [x, y, z, w, l, h, r, velo*].
Returns:
torch.Tensor: Decoded boxes.
"""
cas
,
cts
=
[],
[]
box_ndim
=
anchors
.
shape
[
-
1
]
if
box_ndim
>
7
:
xa
,
ya
,
za
,
wa
,
la
,
ha
,
ra
,
*
cas
=
torch
.
split
(
anchors
,
1
,
dim
=-
1
)
xt
,
yt
,
zt
,
wt
,
lt
,
ht
,
rt
,
*
cts
=
torch
.
split
(
box_encodings
,
1
,
dim
=-
1
)
xt
,
yt
,
zt
,
wt
,
lt
,
ht
,
rt
,
*
cts
=
torch
.
split
(
deltas
,
1
,
dim
=-
1
)
else
:
xa
,
ya
,
za
,
wa
,
la
,
ha
,
ra
=
torch
.
split
(
anchors
,
1
,
dim
=-
1
)
xt
,
yt
,
zt
,
wt
,
lt
,
ht
,
rt
=
torch
.
split
(
box_encoding
s
,
1
,
dim
=-
1
)
xt
,
yt
,
zt
,
wt
,
lt
,
ht
,
rt
=
torch
.
split
(
delta
s
,
1
,
dim
=-
1
)
za
=
za
+
ha
/
2
diagonal
=
torch
.
sqrt
(
la
**
2
+
wa
**
2
)
...
...
mmdet3d/core/bbox/coders/partial_bin_based_bbox_coder.py
View file @
8f88914d
...
...
@@ -28,9 +28,8 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
"""Encode ground truth to prediction targets.
Args:
gt_bboxes_3d (:obj:BaseInstance3DBoxes): gt bboxes with
shape (n, 7).
gt_labels_3d (Tensor): gt classes.
gt_bboxes_3d (BaseInstance3DBoxes): gt bboxes with shape (n, 7).
gt_labels_3d (torch.Tensor): gt classes.
Returns:
tuple: Targets of center, size and direction.
...
...
@@ -67,7 +66,7 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
- size_res: predicted bbox size residual.
Returns:
Tensor: decoded bbox3d with shape (batch, n, 7)
torch.
Tensor: decoded bbox3d with shape (batch, n, 7)
"""
center
=
bbox_out
[
'center'
]
batch_size
,
num_proposal
=
center
.
shape
[:
2
]
...
...
@@ -99,8 +98,8 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
"""Split predicted features to specific parts.
Args:
preds (Tensor): predicted features to split.
base_xyz (Tensor): coordinates of points.
preds (
torch.
Tensor): predicted features to split.
base_xyz (
torch.
Tensor): coordinates of points.
Returns:
dict: split results.
...
...
@@ -161,8 +160,8 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
regression number from class center angle to current angle.
Args:
angle (Tensor): Angle is from 0-2pi (or -pi~pi),
class center at
0, 1*(2pi/N), 2*(2pi/N) ... (N-1)*(2pi/N)
angle (
torch.
Tensor): Angle is from 0-2pi (or -pi~pi),
class center at
0, 1*(2pi/N), 2*(2pi/N) ... (N-1)*(2pi/N)
.
Returns:
tuple: Encoded discrete class and residual.
...
...
@@ -179,12 +178,12 @@ class PartialBinBasedBBoxCoder(BaseBBoxCoder):
"""Inverse function to angle2class
Args:
angle_cls (Tensor): Angle class to decode.
angle_res (Tensor): Angle residual to decode.
angle_cls (
torch.
Tensor): Angle class to decode.
angle_res (
torch.
Tensor): Angle residual to decode.
limit_period (bool): Whether to limit angle to [-pi, pi].
Returns:
Tensor: angle decoded from angle_cls and angle_res.
torch.
Tensor: angle decoded from angle_cls and angle_res.
"""
angle_per_class
=
2
*
np
.
pi
/
float
(
self
.
num_dir_bins
)
angle_center
=
angle_cls
.
float
()
*
angle_per_class
...
...
mmdet3d/core/bbox/iou_calculators/iou3d_calculator.py
View file @
8f88914d
...
...
@@ -46,13 +46,14 @@ def bbox_overlaps_nearest_3d(bboxes1, bboxes2, mode='iou', is_aligned=False):
"""Calculate nearest 3D IoU
Args:
bboxes1
:
Tensor
,
shape (N, 7+N) [x, y, z, h, w, l, ry, v]
bboxes2
:
Tensor
,
shape (M, 7+N) [x, y, z, h, w, l, ry, v]
mode:
mode (str): "iou" (intersection over union) or iof
bboxes1
(torch.
Tensor
):
shape (N, 7+N) [x, y, z, h, w, l, ry, v]
.
bboxes2
(torch.
Tensor
):
shape (M, 7+N) [x, y, z, h, w, l, ry, v]
.
mode (str): "iou" (intersection over union) or iof
(intersection over foreground).
Return:
iou: (M, N) not support aligned mode currently
torch.Tensor: Bbox overlaps results of bboxes1 and bboxes2
with shape (M, N).(not support aligned mode currently).
"""
assert
bboxes1
.
size
(
-
1
)
>=
7
assert
bboxes2
.
size
(
-
1
)
>=
7
...
...
@@ -74,14 +75,15 @@ def bbox_overlaps_3d(bboxes1, bboxes2, mode='iou', coordinate='camera'):
"""Calculate 3D IoU using cuda implementation
Args:
bboxes1
:
Tensor
,
shape (N, 7) [x, y, z, h, w, l, ry]
bboxes2
:
Tensor
,
shape (M, 7) [x, y, z, h, w, l, ry]
mode:
mode (str): "iou" (intersection over union) or
bboxes1
(torch.
Tensor
):
shape (N, 7) [x, y, z, h, w, l, ry]
.
bboxes2
(torch.
Tensor
):
shape (M, 7) [x, y, z, h, w, l, ry]
.
mode (str): "iou" (intersection over union) or
iof (intersection over foreground).
coordinate (str): 'camera' or 'lidar' coordinate system
coordinate (str): 'camera' or 'lidar' coordinate system
.
Return:
iou: (M, N) not support aligned mode currently
torch.Tensor: Bbox overlaps results of bboxes1 and bboxes2
with shape (M, N).(not support aligned mode currently).
"""
assert
bboxes1
.
size
(
-
1
)
==
bboxes2
.
size
(
-
1
)
==
7
assert
coordinate
in
[
'camera'
,
'lidar'
]
...
...
mmdet3d/core/bbox/samplers/iou_neg_piecewise_sampler.py
View file @
8f88914d
...
...
@@ -6,7 +6,7 @@ from . import RandomSampler, SamplingResult
@
BBOX_SAMPLERS
.
register_module
()
class
IoUNegPiecewiseSampler
(
RandomSampler
):
"""IoU Piece-wise Sampling
"""IoU Piece-wise Sampling
.
Sampling negtive proposals according to a list of IoU thresholds.
The negtive proposals are divided into several pieces according
...
...
mmdet3d/core/bbox/structures/base_box3d.py
View file @
8f88914d
...
...
@@ -247,7 +247,7 @@ class BaseInstance3DBoxes(object):
"""Scale the box with horizontal and vertical scaling factors
Args:
scale_factors (float):
s
cale factors to scale the boxes.
scale_factors (float):
S
cale factors to scale the boxes.
"""
self
.
tensor
[:,
:
6
]
*=
scale_factor
self
.
tensor
[:,
7
:]
*=
scale_factor
...
...
@@ -256,8 +256,8 @@ class BaseInstance3DBoxes(object):
"""Limit the yaw to a given period and offset
Args:
offset (float):
t
he offset of the yaw
period (float):
t
he expected period
offset (float):
T
he offset of the yaw
.
period (float):
T
he expected period
.
"""
self
.
tensor
[:,
6
]
=
limit_period
(
self
.
tensor
[:,
6
],
offset
,
period
)
...
...
@@ -268,10 +268,10 @@ class BaseInstance3DBoxes(object):
if either of its side is no larger than threshold.
Args:
threshold (float):
t
he threshold of minimal sizes
threshold (float):
T
he threshold of minimal sizes
.
Returns:
torch.Tensor:
a
binary vector which represents whether each
torch.Tensor:
A
binary vector which represents whether each
box is empty (False) or non-empty (True).
"""
box
=
self
.
tensor
...
...
@@ -321,11 +321,11 @@ class BaseInstance3DBoxes(object):
def
cat
(
cls
,
boxes_list
):
"""Concatenates a list of Boxes into a single Boxes
Arg
ument
s:
boxes_list (list[Boxes])
Args:
boxes_list (list[Boxes])
: List of boxes.
Returns:
Boxes:
t
he concatenated Boxes
Boxes:
T
he concatenated Boxes
.
"""
assert
isinstance
(
boxes_list
,
(
list
,
tuple
))
if
len
(
boxes_list
)
==
0
:
...
...
@@ -365,7 +365,7 @@ class BaseInstance3DBoxes(object):
"""Yield a box as a Tensor of shape (4,) at a time.
Returns:
torch.Tensor:
a
box of shape (4,).
torch.Tensor:
A
box of shape (4,).
"""
yield
from
self
.
tensor
...
...
@@ -378,12 +378,12 @@ class BaseInstance3DBoxes(object):
boxes2, boxes1 and boxes2 should be in the same type.
Args:
boxes1 (:obj:BaseInstanceBoxes):
b
oxes 1 contain N boxes
boxes2 (:obj:BaseInstanceBoxes):
b
oxes 2 contain M boxes
mode (str, optional):
m
ode of iou calculation. Defaults to 'iou'.
boxes1 (:obj:BaseInstanceBoxes):
B
oxes 1 contain N boxes
.
boxes2 (:obj:BaseInstanceBoxes):
B
oxes 2 contain M boxes
.
mode (str, optional):
M
ode of iou calculation. Defaults to 'iou'.
Returns:
torch.Tensor: Calculated iou of boxes
torch.Tensor: Calculated iou of boxes
.
"""
assert
isinstance
(
boxes1
,
BaseInstance3DBoxes
)
assert
isinstance
(
boxes2
,
BaseInstance3DBoxes
)
...
...
@@ -410,12 +410,12 @@ class BaseInstance3DBoxes(object):
boxes1 and boxes2 are not necessarily to be in the same type.
Args:
boxes1 (:obj:BaseInstanceBoxes):
b
oxes 1 contain N boxes
boxes2 (:obj:BaseInstanceBoxes):
b
oxes 2 contain M boxes
mode (str, optional):
m
ode of iou calculation. Defaults to 'iou'.
boxes1 (:obj:BaseInstanceBoxes):
B
oxes 1 contain N boxes
.
boxes2 (:obj:BaseInstanceBoxes):
B
oxes 2 contain M boxes
.
mode (str, optional):
M
ode of iou calculation. Defaults to 'iou'.
Returns:
torch.Tensor: Calculated iou of boxes
torch.Tensor: Calculated iou of boxes
.
"""
assert
isinstance
(
boxes1
,
BaseInstance3DBoxes
)
assert
isinstance
(
boxes2
,
BaseInstance3DBoxes
)
...
...
mmdet3d/core/bbox/structures/box_3d_mode.py
View file @
8f88914d
...
...
@@ -62,19 +62,19 @@ class Box3DMode(IntEnum):
"""Convert boxes from `src` mode to `dst` mode.
Args:
box (tuple | list | np.
n
darray |
box (tuple | list | np.d
n
array |
torch.Tensor | BaseInstance3DBoxes):
c
an be a k-tuple, k-list or an Nxk array/tensor, where k = 7
src (BoxMode):
t
he src Box mode
dst (BoxMode):
t
he target Box mode
rt_mat (np.
n
darray | torch.Tensor): The rotation and translation
C
an be a k-tuple, k-list or an Nxk array/tensor, where k = 7
.
src (BoxMode):
T
he src Box mode
.
dst (BoxMode):
T
he target Box mode
.
rt_mat (np.d
n
array | torch.Tensor): The rotation and translation
matrix between different coordinates. Defaults to None.
The conversion from `src` coordinates to `dst` coordinates
usually comes along the change of sensors, e.g., from camera
to LiDAR. This requires a transformation matrix.
Returns:
(tuple | list | np.
n
darray | torch.Tensor | BaseInstance3DBoxes):
(tuple | list | np.d
n
array | torch.Tensor | BaseInstance3DBoxes):
The converted box of the same type.
"""
if
src
==
dst
:
...
...
mmdet3d/core/bbox/structures/cam_box3d.py
View file @
8f88914d
...
...
@@ -6,7 +6,7 @@ from .utils import limit_period, rotation_3d_in_axis
class
CameraInstance3DBoxes
(
BaseInstance3DBoxes
):
"""3D boxes of instances in CAM coordinates
"""3D boxes of instances in CAM coordinates
.
Coordinates in camera:
.. code-block:: none
...
...
@@ -26,10 +26,10 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
the positive direction of x to the positive direction of z.
Attributes:
tensor (torch.Tensor):
f
loat matrix of N x box_dim.
box_dim (int):
i
nteger indicates the dimension of a box
tensor (torch.Tensor):
F
loat matrix of N x box_dim.
box_dim (int):
I
nteger indicates the dimension of a box
Each row is (x, y, z, x_size, y_size, z_size, yaw, ...).
with_yaw (bool):
i
f True, the value of yaw will be set to 0 as minmax
with_yaw (bool):
I
f True, the value of yaw will be set to 0 as minmax
boxes.
"""
...
...
@@ -38,7 +38,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
"""Obtain the height of all the boxes.
Returns:
torch.Tensor:
a
vector with height of each box.
torch.Tensor:
A
vector with height of each box.
"""
return
self
.
tensor
[:,
4
]
...
...
@@ -47,7 +47,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
"""Obtain the top height of all the boxes.
Returns:
torch.Tensor:
a
vector with the top height of each box.
torch.Tensor:
A
vector with the top height of each box.
"""
# the positive direction is down rather than up
return
self
.
bottom_height
-
self
.
height
...
...
@@ -57,7 +57,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
"""Obtain the bottom's height of all the boxes.
Returns:
torch.Tensor:
a
vector with bottom's height of each box.
torch.Tensor:
A
vector with bottom's height of each box.
"""
return
self
.
tensor
[:,
1
]
...
...
@@ -66,7 +66,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
"""Calculate the gravity center of all the boxes.
Returns:
torch.Tensor:
a
tensor with center of each box.
torch.Tensor:
A
tensor with center of each box.
"""
bottom_center
=
self
.
bottom_center
gravity_center
=
torch
.
zeros_like
(
bottom_center
)
...
...
@@ -99,7 +99,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
down y
Returns:
torch.Tensor:
c
orners of each box with size (N, 8, 3)
torch.Tensor:
C
orners of each box with size (N, 8, 3)
"""
# TODO: rotation_3d_in_axis function do not support
# empty tensor currently.
...
...
@@ -124,7 +124,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
"""Calculate the 2D bounding boxes in BEV with rotation
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.
The box is in XYWHR format.
"""
return
self
.
tensor
[:,
[
0
,
2
,
3
,
5
,
6
]]
...
...
@@ -134,7 +134,7 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
"""Calculate the 2D bounding boxes in BEV without rotation
Returns:
torch.Tensor:
a
tensor of 2D BEV box of each box.
torch.Tensor:
A
tensor of 2D BEV box of each box.
"""
# Obtain BEV boxes with rotation in XZWHR format
bev_rotated_boxes
=
self
.
bev
...
...
@@ -221,8 +221,8 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
"""Check whether the boxes are in the given range
Args:
box_range (list | torch.Tensor):
t
he range of box
(x_min, z_min, x_max, z_max)
box_range (list | torch.Tensor):
T
he range of box
(x_min, z_min, x_max, z_max)
.
Note:
In the original implementation of SECOND, checking whether
...
...
@@ -249,12 +249,12 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
boxes2, boxes1 and boxes2 should be in the same type.
Args:
boxes1 (:obj:BaseInstanceBoxes):
b
oxes 1 contain N boxes
boxes2 (:obj:BaseInstanceBoxes):
b
oxes 2 contain M boxes
mode (str, optional):
m
ode of iou calculation. Defaults to 'iou'.
boxes1 (:obj:BaseInstanceBoxes):
B
oxes 1 contain N boxes
.
boxes2 (:obj:BaseInstanceBoxes):
B
oxes 2 contain M boxes
.
mode (str, optional):
M
ode of iou calculation. Defaults to 'iou'.
Returns:
torch.Tensor: Calculated iou of boxes
torch.Tensor: Calculated iou of boxes
.
"""
assert
isinstance
(
boxes1
,
BaseInstance3DBoxes
)
assert
isinstance
(
boxes2
,
BaseInstance3DBoxes
)
...
...
@@ -278,8 +278,8 @@ class CameraInstance3DBoxes(BaseInstance3DBoxes):
"""Convert self to `dst` mode.
Args:
dst (BoxMode):
t
he target Box mode
rt_mat (np.
n
darray | torch.Tensor): The rotation and translation
dst (BoxMode):
T
he target Box mode
.
rt_mat (np.d
n
array | torch.Tensor): The rotation and translation
matrix between different coordinates. Defaults to None.
The conversion from `src` coordinates to `dst` coordinates
usually comes along the change of sensors, e.g., from camera
...
...
mmdet3d/core/bbox/structures/depth_box3d.py
View file @
8f88914d
...
...
@@ -7,7 +7,7 @@ from .utils import limit_period, rotation_3d_in_axis
class
DepthInstance3DBoxes
(
BaseInstance3DBoxes
):
"""3D boxes of instances in Depth coordinates
"""3D boxes of instances in Depth coordinates
.
Coordinates in Depth:
.. code-block:: none
...
...
@@ -23,11 +23,11 @@ class DepthInstance3DBoxes(BaseInstance3DBoxes):
The yaw is 0 at the positive direction of x axis, and increases from
the positive direction of x to the positive direction of y.
A
ttribute
s:
tensor (
torch.
Tensor):
f
loat matrix of N x box_dim.
box_dim (int):
i
nteger indicates the dimension of a box
A
rg
s:
tensor (Tensor):
F
loat matrix of N x box_dim.
box_dim (int):
I
nteger indicates the dimension of a box
Each row is (x, y, z, x_size, y_size, z_size, yaw, ...).
with_yaw (bool):
i
f True, the value of yaw will be set to 0 as minmax
with_yaw (bool):
I
f True, the value of yaw will be set to 0 as minmax
boxes.
"""
...
...
@@ -89,17 +89,17 @@ class DepthInstance3DBoxes(BaseInstance3DBoxes):
@
property
def
bev
(
self
):
"""Calculate the 2D bounding boxes in BEV with rotation
"""Calculate the 2D bounding boxes in BEV with rotation
.
Returns:
torch.Tensor:
a
nx5 tensor of 2D BEV box of each box.
The box is in XYWHR format
torch.Tensor:
A
nx5 tensor of 2D BEV box of each box.
The box is in XYWHR format
.
"""
return
self
.
tensor
[:,
[
0
,
1
,
3
,
4
,
6
]]
@
property
def
nearest_bev
(
self
):
"""Calculate the 2D bounding boxes in BEV without rotation
"""Calculate the 2D bounding boxes in BEV without rotation
.
Returns:
torch.Tensor: a tensor of 2D BEV box of each box.
...
...
@@ -196,11 +196,11 @@ class DepthInstance3DBoxes(BaseInstance3DBoxes):
return
points
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:
box_range (list | torch.Tensor):
t
he range of box
(x_min, y_min, x_max, y_max)
box_range (list | torch.Tensor):
T
he range of box
(x_min, y_min, x_max, y_max)
.
Note:
In the original implementation of SECOND, checking whether
...
...
@@ -222,7 +222,7 @@ class DepthInstance3DBoxes(BaseInstance3DBoxes):
"""Convert self to `dst` mode.
Args:
dst (BoxMode):
t
he target Box mode
dst (BoxMode):
T
he target Box mode
.
rt_mat (np.ndarray | torch.Tensor): The rotation and translation
matrix between different coordinates. Defaults to None.
The conversion from `src` coordinates to `dst` coordinates
...
...
@@ -238,7 +238,7 @@ class DepthInstance3DBoxes(BaseInstance3DBoxes):
box
=
self
,
src
=
Box3DMode
.
DEPTH
,
dst
=
dst
,
rt_mat
=
rt_mat
)
def
points_in_boxes
(
self
,
points
):
"""Find points that are in boxes (CUDA)
"""Find points that are in boxes (CUDA)
.
Args:
points (torch.Tensor): [1, M, 3] or [M, 3], [x, y, z]
...
...
mmdet3d/core/bbox/structures/lidar_box3d.py
View file @
8f88914d
...
...
@@ -24,10 +24,10 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes):
the negative direction of y to the positive direction of x.
Attributes:
tensor (torch.Tensor):
f
loat matrix of N x box_dim.
box_dim (int):
i
nteger indicates the dimension of a box
tensor (torch.Tensor):
F
loat matrix of N x box_dim.
box_dim (int):
I
nteger indicates the dimension of a box
Each row is (x, y, z, x_size, y_size, z_size, yaw, ...).
with_yaw (bool):
i
f True, the value of yaw will be set to 0 as minmax
with_yaw (bool):
I
f True, the value of yaw will be set to 0 as minmax
boxes.
"""
...
...
@@ -36,7 +36,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes):
"""Calculate the gravity center of all the boxes.
Returns:
torch.Tensor:
a
tensor with center of each box.
torch.Tensor:
A
tensor with center of each box.
"""
bottom_center
=
self
.
bottom_center
gravity_center
=
torch
.
zeros_like
(
bottom_center
)
...
...
@@ -92,7 +92,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes):
"""Calculate the 2D bounding boxes in BEV with rotation
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.
The box is in XYWHR format
"""
return
self
.
tensor
[:,
[
0
,
1
,
3
,
4
,
6
]]
...
...
@@ -102,7 +102,7 @@ class LiDARInstance3DBoxes(BaseInstance3DBoxes):
"""Calculate the 2D bounding boxes in BEV without rotation
Returns:
torch.Tensor:
a
tensor of 2D BEV box of each box.
torch.Tensor:
A
tensor of 2D BEV box of each box.
"""
# Obtain BEV boxes with rotation in XYWHR format
bev_rotated_boxes
=
self
.
bev
...
...
mmdet3d/core/bbox/structures/utils.py
View file @
8f88914d
...
...
@@ -6,7 +6,7 @@ def limit_period(val, offset=0.5, period=np.pi):
"""Limit the value into a period for periodic function.
Args:
val (torch.Tensor): The value to be converted
val (torch.Tensor): The value to be converted
.
offset (float, optional): Offset to set the value range.
Defaults to 0.5.
period ([type], optional): Period of the value. Defaults to np.pi.
...
...
mmdet3d/core/bbox/transforms.py
View file @
8f88914d
...
...
@@ -14,10 +14,17 @@ def bbox3d_mapping_back(bboxes, scale_factor, flip_horizontal, flip_vertical):
def
transform_lidar_to_cam
(
boxes_lidar
):
"""
Only transform format, not exactly in camera coords
:param boxes_lidar: (N, 3 or 7) [x, y, z, w, l, h, ry] in LiDAR coords
:return: boxes_cam: (N, 3 or 7) [x, y, z, h, w, l, ry] in camera coords
"""Transform boxes from lidar coords to cam coords.
Only transform format, not exactly in camera coords.
Args:
boxes_lidar (torch.Tensor): (N, 3 or 7) [x, y, z, w, l, h, ry]
in LiDAR coords.
boxes_cam (torch.Tensor): (N, 3 or 7) [x, y, z, h, w, l, ry]
in camera coords.
Returns:
torch.Tensor: Boxes in camera coords.
"""
# boxes_cam = boxes_lidar.new_tensor(boxes_lidar.data)
boxes_cam
=
boxes_lidar
.
clone
().
detach
()
...
...
@@ -30,10 +37,15 @@ def transform_lidar_to_cam(boxes_lidar):
def
boxes3d_to_bev_torch
(
boxes3d
):
"""
:param boxes3d: (N, 7) [x, y, z, h, w, l, ry] in camera coords
:return:
boxes_bev: (N, 5) [x1, y1, x2, y2, ry]
"""Transform 3d boxes to bev in camera coords.
Args:
boxes3d (torch.Tensor): 3d boxes in camera coords
with the shape of [N, 7] (x, y, z, h, w, l, ry).
Returns:
torch.Tensor: Bev boxes with the shape of [N, 5]
(x1, y1, x2, y2, ry).
"""
boxes_bev
=
boxes3d
.
new
(
torch
.
Size
((
boxes3d
.
shape
[
0
],
5
)))
...
...
@@ -46,10 +58,13 @@ def boxes3d_to_bev_torch(boxes3d):
def
boxes3d_to_bev_torch_lidar
(
boxes3d
):
"""
:param boxes3d: (N, 7) [x, y, z, w, l, h, ry] in LiDAR coords
:return:
boxes_bev: (N, 5) [x1, y1, x2, y2, ry]
"""Transform 3d boxes to bev in lidar coords.
Args:
boxes3d (torch.Tensor): 3d boxes in lidar coords
with the shape of [N, 7] (x, y, z, h, w, l, ry).
Returns: Bev boxes with the shape of [N, 5] (x1, y1, x2, y2, ry).
"""
boxes_bev
=
boxes3d
.
new
(
torch
.
Size
((
boxes3d
.
shape
[
0
],
5
)))
...
...
@@ -65,11 +80,11 @@ def bbox3d2roi(bbox_list):
"""Convert a list of bboxes to roi format.
Args:
bbox_list (list[Tensor]): a list of bboxes
corresponding to a batch
of images.
bbox_list (list[
torch.
Tensor]): a list of bboxes
corresponding to a batch
of images.
Returns:
Tensor: shape (n, c), [batch_ind, x, y ...]
torch.
Tensor: shape (n, c), [batch_ind, x, y ...]
.
"""
rois_list
=
[]
for
img_id
,
bboxes
in
enumerate
(
bbox_list
):
...
...
@@ -87,12 +102,12 @@ def bbox3d2result(bboxes, scores, labels):
"""Convert detection results to a list of numpy arrays.
Args:
bboxes (Tensor): shape (n, 5)
labels (Tensor): shape (n, )
scores (Tensor): shape (n, )
bboxes (
torch.
Tensor): shape (n, 5)
labels (
torch.
Tensor): shape (n, )
scores (
torch.
Tensor): shape (n, )
Returns:
dict(Tensor):
b
box results in cpu mode
dict(
torch.
Tensor):
B
box results in cpu mode
.
"""
return
dict
(
boxes_3d
=
bboxes
.
to
(
'cpu'
),
...
...
@@ -106,8 +121,8 @@ def upright_depth_to_lidar_torch(points=None,
"""Convert points and boxes in upright depth coordinate to lidar.
Args:
points (None | Tensor): points in upright depth coordinate.
bboxes (None | Tensor): bboxes in upright depth coordinate.
points (None |
torch.
Tensor): points in upright depth coordinate.
bboxes (None |
torch.
Tensor): bboxes in upright depth coordinate.
to_bottom_center (bool): covert bboxes to bottom center.
Returns:
...
...
@@ -136,10 +151,11 @@ def box3d_to_corner3d_upright_depth(boxes3d):
"""Convert box3d to corner3d in upright depth coordinate
Args:
boxes3d (Tensor): boxes with shape [n,7] in upright depth coordinate
boxes3d (torch.Tensor): boxes with shape [n,7] in
upright depth coordinate.
Returns:
Tensor: boxes with [n, 8, 3] in upright depth coordinate
torch.
Tensor: boxes with [n, 8, 3] in upright depth coordinate
"""
boxes_num
=
boxes3d
.
shape
[
0
]
ry
=
boxes3d
[:,
6
:
7
]
...
...
mmdet3d/core/evaluation/indoor_eval.py
View file @
8f88914d
...
...
@@ -8,14 +8,14 @@ def average_precision(recalls, precisions, mode='area'):
"""Calculate average precision (for single or multiple scales).
Args:
recalls (ndarray): shape (num_scales, num_dets) or (num_dets, )
precisions (ndarray): shape (num_scales, num_dets) or (num_dets, )
recalls (
np.
ndarray): shape (num_scales, num_dets) or (num_dets, )
precisions (
np.
ndarray): shape (num_scales, num_dets) or (num_dets, )
mode (str): 'area' or '11points', 'area' means calculating the area
under precision-recall curve, '11points' means calculating
the average precision of recalls at [0, 0.1, ..., 1]
Returns:
float or ndarray: calculated average precision
float or
np.
ndarray: calculated average precision
"""
if
recalls
.
ndim
==
1
:
recalls
=
recalls
[
np
.
newaxis
,
:]
...
...
@@ -60,8 +60,8 @@ def eval_det_cls(pred, gt, iou_thr=None):
iou_thr (list[float]): a list, iou threshold.
Return:
ndarray: numpy array of length nd.
ndarray: numpy array of length nd.
np.
ndarray: numpy array of length nd.
np.
ndarray: numpy array of length nd.
float: scalar, average precision.
"""
...
...
@@ -204,7 +204,7 @@ def indoor_eval(gt_annos,
logger
=
None
,
box_type_3d
=
None
,
box_mode_3d
=
None
):
"""
Scannet
Evaluation.
"""
Indoor
Evaluation.
Evaluate the result of the detection.
...
...
@@ -212,10 +212,9 @@ def indoor_eval(gt_annos,
gt_annos (list[dict]): GT annotations.
dt_annos (list[dict]): Detection annotations. the dict
includes the following keys
- labels_3d (Tensor): Labels of boxes.
- boxes_3d (:obj:BaseInstance3DBoxes): 3d bboxes in
Depth coordinate.
- scores_3d (Tensor): Scores of boxes.
- labels_3d (torch.Tensor): Labels of boxes.
- boxes_3d (BaseInstance3DBoxes): 3d bboxes in Depth coordinate.
- scores_3d (torch.Tensor): Scores of boxes.
metric (list[float]): AP IoU thresholds.
label2cat (dict): {label: cat}.
logger (logging.Logger | str | None): The way to print the mAP
...
...
mmdet3d/core/evaluation/kitti_utils/eval.py
View file @
8f88914d
...
...
@@ -340,13 +340,14 @@ def fused_compute_statistics(overlaps,
def
calculate_iou_partly
(
gt_annos
,
dt_annos
,
metric
,
num_parts
=
50
):
"""
f
ast iou algorithm. this function can be used independently to
"""
F
ast iou algorithm. this function can be used independently to
do result analysis. Must be used in CAMERA coordinate system.
Args:
gt_annos
:
dict
, m
ust from get_label_annos() in kitti_common.py
dt_annos
:
dict
, m
ust from get_label_annos() in kitti_common.py
metric:
e
val type. 0: bbox, 1: bev, 2: 3d
num_parts
:
int
. a
parameter for fast calculate algorithm
gt_annos
(
dict
): M
ust from get_label_annos() in kitti_common.py
.
dt_annos
(
dict
): M
ust from get_label_annos() in kitti_common.py
.
metric
(int)
:
E
val type. 0: bbox, 1: bev, 2: 3d
.
num_parts
(
int
): A
parameter for fast calculate algorithm
.
"""
assert
len
(
gt_annos
)
==
len
(
dt_annos
)
total_dt_num
=
np
.
stack
([
len
(
a
[
'name'
])
for
a
in
dt_annos
],
0
)
...
...
@@ -456,17 +457,19 @@ def eval_class(gt_annos,
compute_aos
=
False
,
num_parts
=
200
):
"""Kitti eval. support 2d/bev/3d/aos eval. support 0.5:0.05:0.95 coco AP.
Args:
gt_annos: dict, must from get_label_annos() in kitti_common.py
dt_annos: dict, must from get_label_annos() in kitti_common.py
current_classes: list of int, 0: car, 1: pedestrian, 2: cyclist
difficultys: list of int. eval difficulty, 0: easy, 1: normal, 2: hard
metric: eval type. 0: bbox, 1: bev, 2: 3d
min_overlaps: float, min overlap. format: [num_overlap, metric, class].
num_parts: int. a parameter for fast calculate algorithm
gt_annos (dict): Must from get_label_annos() in kitti_common.py.
dt_annos (dict): Must from get_label_annos() in kitti_common.py.
current_classes (list[int]): 0: car, 1: pedestrian, 2: cyclist.
difficultys (list[int]): Eval difficulty, 0: easy, 1: normal, 2: hard
metric (int): Eval type. 0: bbox, 1: bev, 2: 3d
min_overlaps (float): Min overlap. format:
[num_overlap, metric, class].
num_parts (int): A parameter for fast calculate algorithm
Returns:
dict
of
recall, precision and aos
dict
:
recall, precision and aos
"""
assert
len
(
gt_annos
)
==
len
(
dt_annos
)
num_examples
=
len
(
gt_annos
)
...
...
mmdet3d/core/evaluation/kitti_utils/rotate_iou.py
View file @
8f88914d
...
...
@@ -304,19 +304,19 @@ def rotate_iou_kernel_eval(N,
def
rotate_iou_gpu_eval
(
boxes
,
query_boxes
,
criterion
=-
1
,
device_id
=
0
):
"""
r
otated box iou running in gpu. 500x faster than cpu version
"""
R
otated box iou running in gpu. 500x faster than cpu version
(take 5ms in one example with numba.cuda code).
convert from [this project](
https://github.com/hongzhenwang/RRPN-revise/tree/master/lib/rotation).
Args:
boxes (
float tensor: [N, 5]
): rbboxes. format: centers, dims,
angles(clockwise when positive)
boxes (
torch.Tensor
): rbboxes. format: centers, dims,
angles(clockwise when positive)
with the shape of [N, 5].
query_boxes (float tensor: [K, 5]): [description]
device_id (int, optional): Defaults to 0. [description]
Returns:
[type]: [description]
np.ndarray: IoU results.
"""
boxes
=
boxes
.
astype
(
np
.
float32
)
query_boxes
=
query_boxes
.
astype
(
np
.
float32
)
...
...
mmdet3d/core/post_processing/box3d_nms.py
View file @
8f88914d
...
...
@@ -70,13 +70,13 @@ def aligned_3d_nms(boxes, scores, classes, thresh):
"""3d nms for aligned boxes.
Args:
boxes (Tensor): Aligned box with shape [n, 6].
scores (Tensor): Scores of each box.
classes (Tensor): Class of each box.
boxes (
torch.
Tensor): Aligned box with shape [n, 6].
scores (
torch.
Tensor): Scores of each box.
classes (
torch.
Tensor): Class of each box.
thresh (float): Iou threshold for nms.
Returns:
Tensor: Indices of selected boxes.
torch.
Tensor: Indices of selected boxes.
"""
x1
=
boxes
[:,
0
]
y1
=
boxes
[:,
1
]
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment