Commit 2eebdc2d authored by Yezhen Cong's avatar Yezhen Cong Committed by Tai-Wang
Browse files

[Refactor] Main code modification for coordinate system refactor (#677)

parent 26ab7ff2
...@@ -293,6 +293,7 @@ class AnchorTrainMixin(object): ...@@ -293,6 +293,7 @@ class AnchorTrainMixin(object):
sampling_result.pos_bboxes, sampling_result.pos_bboxes,
pos_bbox_targets, pos_bbox_targets,
self.dir_offset, self.dir_offset,
self.dir_limit_offset,
one_hot=False) one_hot=False)
bbox_targets[pos_inds, :] = pos_bbox_targets bbox_targets[pos_inds, :] = pos_bbox_targets
bbox_weights[pos_inds, :] = 1.0 bbox_weights[pos_inds, :] = 1.0
...@@ -318,6 +319,7 @@ class AnchorTrainMixin(object): ...@@ -318,6 +319,7 @@ class AnchorTrainMixin(object):
def get_direction_target(anchors, def get_direction_target(anchors,
reg_targets, reg_targets,
dir_offset=0, dir_offset=0,
dir_limit_offset=0,
num_bins=2, num_bins=2,
one_hot=True): one_hot=True):
"""Encode direction to 0 ~ num_bins-1. """Encode direction to 0 ~ num_bins-1.
...@@ -333,7 +335,7 @@ def get_direction_target(anchors, ...@@ -333,7 +335,7 @@ def get_direction_target(anchors,
torch.Tensor: Encoded direction targets. torch.Tensor: Encoded direction targets.
""" """
rot_gt = reg_targets[..., 6] + anchors[..., 6] rot_gt = reg_targets[..., 6] + anchors[..., 6]
offset_rot = limit_period(rot_gt - dir_offset, 0, 2 * np.pi) offset_rot = limit_period(rot_gt - dir_offset, dir_limit_offset, 2 * np.pi)
dir_cls_targets = torch.floor(offset_rot / (2 * np.pi / num_bins)).long() dir_cls_targets = torch.floor(offset_rot / (2 * np.pi / num_bins)).long()
dir_cls_targets = torch.clamp(dir_cls_targets, min=0, max=num_bins - 1) dir_cls_targets = torch.clamp(dir_cls_targets, min=0, max=num_bins - 1)
if one_hot: if one_hot:
......
...@@ -471,7 +471,7 @@ class VoteHead(BaseModule): ...@@ -471,7 +471,7 @@ class VoteHead(BaseModule):
vote_target_masks = points.new_zeros([num_points], vote_target_masks = points.new_zeros([num_points],
dtype=torch.long) dtype=torch.long)
vote_target_idx = points.new_zeros([num_points], dtype=torch.long) vote_target_idx = points.new_zeros([num_points], dtype=torch.long)
box_indices_all = gt_bboxes_3d.points_in_boxes(points) box_indices_all = gt_bboxes_3d.points_in_boxes_batch(points)
for i in range(gt_labels_3d.shape[0]): for i in range(gt_labels_3d.shape[0]):
box_indices = box_indices_all[:, i] box_indices = box_indices_all[:, i]
indices = torch.nonzero( indices = torch.nonzero(
...@@ -621,7 +621,7 @@ class VoteHead(BaseModule): ...@@ -621,7 +621,7 @@ class VoteHead(BaseModule):
box_dim=bbox.shape[-1], box_dim=bbox.shape[-1],
with_yaw=self.bbox_coder.with_rot, with_yaw=self.bbox_coder.with_rot,
origin=(0.5, 0.5, 0.5)) origin=(0.5, 0.5, 0.5))
box_indices = bbox.points_in_boxes(points) box_indices = bbox.points_in_boxes_batch(points)
corner3d = bbox.corners corner3d = bbox.corners
minmax_box3d = corner3d.new(torch.Size((corner3d.shape[0], 6))) minmax_box3d = corner3d.new(torch.Size((corner3d.shape[0], 6)))
......
...@@ -502,7 +502,7 @@ class H3DBboxHead(BaseModule): ...@@ -502,7 +502,7 @@ class H3DBboxHead(BaseModule):
box_dim=bbox.shape[-1], box_dim=bbox.shape[-1],
with_yaw=self.bbox_coder.with_rot, with_yaw=self.bbox_coder.with_rot,
origin=(0.5, 0.5, 0.5)) origin=(0.5, 0.5, 0.5))
box_indices = bbox.points_in_boxes(points) box_indices = bbox.points_in_boxes_batch(points)
corner3d = bbox.corners corner3d = bbox.corners
minmax_box3d = corner3d.new(torch.Size((corner3d.shape[0], 6))) minmax_box3d = corner3d.new(torch.Size((corner3d.shape[0], 6)))
......
...@@ -344,7 +344,7 @@ class PartA2BboxHead(BaseModule): ...@@ -344,7 +344,7 @@ class PartA2BboxHead(BaseModule):
pred_boxes3d[..., 0:3] = rotation_3d_in_axis( pred_boxes3d[..., 0:3] = rotation_3d_in_axis(
pred_boxes3d[..., 0:3].unsqueeze(1), pred_boxes3d[..., 0:3].unsqueeze(1),
(pos_rois_rotation + np.pi / 2), pos_rois_rotation,
axis=2).squeeze(1) axis=2).squeeze(1)
pred_boxes3d[:, 0:3] += roi_xyz pred_boxes3d[:, 0:3] += roi_xyz
...@@ -436,8 +436,7 @@ class PartA2BboxHead(BaseModule): ...@@ -436,8 +436,7 @@ class PartA2BboxHead(BaseModule):
pos_gt_bboxes_ct[..., 0:3] -= roi_center pos_gt_bboxes_ct[..., 0:3] -= roi_center
pos_gt_bboxes_ct[..., 6] -= roi_ry pos_gt_bboxes_ct[..., 6] -= roi_ry
pos_gt_bboxes_ct[..., 0:3] = rotation_3d_in_axis( pos_gt_bboxes_ct[..., 0:3] = rotation_3d_in_axis(
pos_gt_bboxes_ct[..., 0:3].unsqueeze(1), pos_gt_bboxes_ct[..., 0:3].unsqueeze(1), -roi_ry,
-(roi_ry + np.pi / 2),
axis=2).squeeze(1) axis=2).squeeze(1)
# flip orientation if rois have opposite orientation # flip orientation if rois have opposite orientation
...@@ -530,8 +529,7 @@ class PartA2BboxHead(BaseModule): ...@@ -530,8 +529,7 @@ class PartA2BboxHead(BaseModule):
local_roi_boxes[..., 0:3] = 0 local_roi_boxes[..., 0:3] = 0
rcnn_boxes3d = self.bbox_coder.decode(local_roi_boxes, bbox_pred) rcnn_boxes3d = self.bbox_coder.decode(local_roi_boxes, bbox_pred)
rcnn_boxes3d[..., 0:3] = rotation_3d_in_axis( rcnn_boxes3d[..., 0:3] = rotation_3d_in_axis(
rcnn_boxes3d[..., 0:3].unsqueeze(1), (roi_ry + np.pi / 2), rcnn_boxes3d[..., 0:3].unsqueeze(1), roi_ry, axis=2).squeeze(1)
axis=2).squeeze(1)
rcnn_boxes3d[:, 0:3] += roi_xyz rcnn_boxes3d[:, 0:3] += roi_xyz
# post processing # post processing
......
...@@ -355,7 +355,7 @@ class PrimitiveHead(BaseModule): ...@@ -355,7 +355,7 @@ class PrimitiveHead(BaseModule):
# Generate pts_semantic_mask and pts_instance_mask when they are None # Generate pts_semantic_mask and pts_instance_mask when they are None
if pts_semantic_mask is None or pts_instance_mask is None: if pts_semantic_mask is None or pts_instance_mask is None:
points2box_mask = gt_bboxes_3d.points_in_boxes(points) points2box_mask = gt_bboxes_3d.points_in_boxes_batch(points)
assignment = points2box_mask.argmax(1) assignment = points2box_mask.argmax(1)
background_mask = points2box_mask.max(1)[0] == 0 background_mask = points2box_mask.max(1)[0] == 0
......
...@@ -61,9 +61,9 @@ __device__ inline int check_in_box2d(const float *box, const Point &p) { ...@@ -61,9 +61,9 @@ __device__ inline int check_in_box2d(const float *box, const Point &p) {
angle_sin = angle_sin =
sin(-box[4]); // rotate the point in the opposite direction of box sin(-box[4]); // rotate the point in the opposite direction of box
float rot_x = float rot_x =
(p.x - center_x) * angle_cos + (p.y - center_y) * angle_sin + center_x; (p.x - center_x) * angle_cos - (p.y - center_y) * angle_sin + center_x;
float rot_y = float rot_y =
-(p.x - center_x) * angle_sin + (p.y - center_y) * angle_cos + center_y; (p.x - center_x) * angle_sin + (p.y - center_y) * angle_cos + center_y;
#ifdef DEBUG #ifdef DEBUG
printf("box: (%.3f, %.3f, %.3f, %.3f, %.3f)\n", box[0], box[1], box[2], printf("box: (%.3f, %.3f, %.3f, %.3f, %.3f)\n", box[0], box[1], box[2],
box[3], box[4]); box[3], box[4]);
...@@ -112,9 +112,9 @@ __device__ inline void rotate_around_center(const Point &center, ...@@ -112,9 +112,9 @@ __device__ inline void rotate_around_center(const Point &center,
const float angle_cos, const float angle_cos,
const float angle_sin, Point &p) { const float angle_sin, Point &p) {
float new_x = float new_x =
(p.x - center.x) * angle_cos + (p.y - center.y) * angle_sin + center.x; (p.x - center.x) * angle_cos - (p.y - center.y) * angle_sin + center.x;
float new_y = float new_y =
-(p.x - center.x) * angle_sin + (p.y - center.y) * angle_cos + center.y; (p.x - center.x) * angle_sin + (p.y - center.y) * angle_cos + center.y;
p.set(new_x, new_y); p.set(new_x, new_y);
} }
......
...@@ -7,17 +7,17 @@ def points_in_boxes_gpu(points, boxes): ...@@ -7,17 +7,17 @@ def points_in_boxes_gpu(points, boxes):
"""Find points that are in boxes (CUDA) """Find points that are in boxes (CUDA)
Args: Args:
points (torch.Tensor): [B, M, 3], [x, y, z] in LiDAR coordinate points (torch.Tensor): [B, M, 3], [x, y, z] in LiDAR/DEPTH coordinate
boxes (torch.Tensor): [B, T, 7], boxes (torch.Tensor): [B, T, 7],
num_valid_boxes <= T, [x, y, z, w, l, h, ry] in LiDAR coordinate, num_valid_boxes <= T, [x, y, z, dx, dy, dz, rz] in
(x, y, z) is the bottom center LiDAR/DEPTH coordinate, (x, y, z) is the bottom center
Returns: Returns:
box_idxs_of_pts (torch.Tensor): (B, M), default background = -1 box_idxs_of_pts (torch.Tensor): (B, M), default background = -1
""" """
assert boxes.shape[0] == points.shape[0], \ assert points.shape[0] == boxes.shape[0], \
f'Points and boxes should have the same batch size, ' \ f'Points and boxes should have the same batch size, ' \
f'got {boxes.shape[0]} and {boxes.shape[0]}' f'got {points.shape[0]} and {boxes.shape[0]}'
assert boxes.shape[2] == 7, \ assert boxes.shape[2] == 7, \
f'boxes dimension should be 7, ' \ f'boxes dimension should be 7, ' \
f'got unexpected shape {boxes.shape[2]}' f'got unexpected shape {boxes.shape[2]}'
...@@ -53,31 +53,35 @@ def points_in_boxes_gpu(points, boxes): ...@@ -53,31 +53,35 @@ def points_in_boxes_gpu(points, boxes):
def points_in_boxes_cpu(points, boxes): def points_in_boxes_cpu(points, boxes):
"""Find points that are in boxes (CPU) """Find points that are in boxes (CPU)
Note:
Currently, the output of this function is different from that of
points_in_boxes_gpu.
Args: Args:
points (torch.Tensor): [npoints, 3] points (torch.Tensor): [B, M, 3], [x, y, z] in
boxes (torch.Tensor): [N, 7], in LiDAR coordinate, LiDAR/DEPTH coordinate
(x, y, z) is the bottom center boxes (torch.Tensor): [B, T, 7],
num_valid_boxes <= T, [x, y, z, dx, dy, dz, rz],
(x, y, z) is the bottom center.
Returns: Returns:
point_indices (torch.Tensor): (N, npoints) box_idxs_of_pts (torch.Tensor): (B, M, T), default background = 0
""" """
# TODO: Refactor this function as a CPU version of points_in_boxes_gpu assert points.shape[0] == boxes.shape[0], \
assert boxes.shape[1] == 7, \ f'Points and boxes should have the same batch size, ' \
f'got {points.shape[0]} and {boxes.shape[0]}'
assert boxes.shape[2] == 7, \
f'boxes dimension should be 7, ' \ f'boxes dimension should be 7, ' \
f'got unexpected shape {boxes.shape[2]}' f'got unexpected shape {boxes.shape[2]}'
assert points.shape[1] == 3, \ assert points.shape[2] == 3, \
f'points dimension should be 3, ' \ f'points dimension should be 3, ' \
f'got unexpected shape {points.shape[2]}' f'got unexpected shape {points.shape[2]}'
batch_size, num_points, _ = points.shape
num_boxes = boxes.shape[1]
point_indices = points.new_zeros((boxes.shape[0], points.shape[0]), point_indices = points.new_zeros((batch_size, num_boxes, num_points),
dtype=torch.int) dtype=torch.int)
roiaware_pool3d_ext.points_in_boxes_cpu(boxes.float().contiguous(), for b in range(batch_size):
points.float().contiguous(), roiaware_pool3d_ext.points_in_boxes_cpu(boxes[b].float().contiguous(),
point_indices) points[b].float().contiguous(),
point_indices[b])
point_indices = point_indices.transpose(1, 2)
return point_indices return point_indices
...@@ -86,9 +90,9 @@ def points_in_boxes_batch(points, boxes): ...@@ -86,9 +90,9 @@ def points_in_boxes_batch(points, boxes):
"""Find points that are in boxes (CUDA) """Find points that are in boxes (CUDA)
Args: Args:
points (torch.Tensor): [B, M, 3], [x, y, z] in LiDAR coordinate points (torch.Tensor): [B, M, 3], [x, y, z] in LiDAR/DEPTH coordinate
boxes (torch.Tensor): [B, T, 7], boxes (torch.Tensor): [B, T, 7],
num_valid_boxes <= T, [x, y, z, w, l, h, ry] in LiDAR coordinate, num_valid_boxes <= T, [x, y, z, dx, dy, dz, rz],
(x, y, z) is the bottom center. (x, y, z) is the bottom center.
Returns: Returns:
......
...@@ -15,9 +15,7 @@ ...@@ -15,9 +15,7 @@
inline void lidar_to_local_coords_cpu(float shift_x, float shift_y, float rz, inline void lidar_to_local_coords_cpu(float shift_x, float shift_y, float rz,
float &local_x, float &local_y) { float &local_x, float &local_y) {
// should rotate pi/2 + alpha to translate LiDAR to local float cosa = cos(-rz), sina = sin(-rz);
float rot_angle = rz + M_PI / 2;
float cosa = cos(rot_angle), sina = sin(rot_angle);
local_x = shift_x * cosa + shift_y * (-sina); local_x = shift_x * cosa + shift_y * (-sina);
local_y = shift_x * sina + shift_y * cosa; local_y = shift_x * sina + shift_y * cosa;
} }
...@@ -29,13 +27,13 @@ inline int check_pt_in_box3d_cpu(const float *pt, const float *box3d, ...@@ -29,13 +27,13 @@ inline int check_pt_in_box3d_cpu(const float *pt, const float *box3d,
// bottom center // bottom center
float x = pt[0], y = pt[1], z = pt[2]; float x = pt[0], y = pt[1], z = pt[2];
float cx = box3d[0], cy = box3d[1], cz = box3d[2]; float cx = box3d[0], cy = box3d[1], cz = box3d[2];
float w = box3d[3], l = box3d[4], h = box3d[5], rz = box3d[6]; float dx = box3d[3], dy = box3d[4], dz = box3d[5], rz = box3d[6];
cz += h / 2.0; // shift to the center since cz in box3d is the bottom center cz += dz / 2.0; // shift to the center since cz in box3d is the bottom center
if (fabsf(z - cz) > h / 2.0) return 0; if (fabsf(z - cz) > dz / 2.0) return 0;
lidar_to_local_coords_cpu(x - cx, y - cy, rz, local_x, local_y); lidar_to_local_coords_cpu(x - cx, y - cy, rz, local_x, local_y);
float in_flag = (local_x > -l / 2.0) & (local_x < l / 2.0) & float in_flag = (local_x > -dx / 2.0) & (local_x < dx / 2.0) &
(local_y > -w / 2.0) & (local_y < w / 2.0); (local_y > -dy / 2.0) & (local_y < dy / 2.0);
return in_flag; return in_flag;
} }
......
...@@ -24,9 +24,7 @@ ...@@ -24,9 +24,7 @@
__device__ inline void lidar_to_local_coords(float shift_x, float shift_y, __device__ inline void lidar_to_local_coords(float shift_x, float shift_y,
float rz, float &local_x, float rz, float &local_x,
float &local_y) { float &local_y) {
// should rotate pi/2 + alpha to translate LiDAR to local float cosa = cos(-rz), sina = sin(-rz);
float rot_angle = rz + M_PI / 2;
float cosa = cos(rot_angle), sina = sin(rot_angle);
local_x = shift_x * cosa + shift_y * (-sina); local_x = shift_x * cosa + shift_y * (-sina);
local_y = shift_x * sina + shift_y * cosa; local_y = shift_x * sina + shift_y * cosa;
} }
...@@ -38,13 +36,13 @@ __device__ inline int check_pt_in_box3d(const float *pt, const float *box3d, ...@@ -38,13 +36,13 @@ __device__ inline int check_pt_in_box3d(const float *pt, const float *box3d,
// bottom center // bottom center
float x = pt[0], y = pt[1], z = pt[2]; float x = pt[0], y = pt[1], z = pt[2];
float cx = box3d[0], cy = box3d[1], cz = box3d[2]; float cx = box3d[0], cy = box3d[1], cz = box3d[2];
float w = box3d[3], l = box3d[4], h = box3d[5], rz = box3d[6]; float dx = box3d[3], dy = box3d[4], dz = box3d[5], rz = box3d[6];
cz += h / 2.0; // shift to the center since cz in box3d is the bottom center cz += dz / 2.0; // shift to the center since cz in box3d is the bottom center
if (fabsf(z - cz) > h / 2.0) return 0; if (fabsf(z - cz) > dz / 2.0) return 0;
lidar_to_local_coords(x - cx, y - cy, rz, local_x, local_y); lidar_to_local_coords(x - cx, y - cy, rz, local_x, local_y);
float in_flag = (local_x > -l / 2.0) & (local_x < l / 2.0) & float in_flag = (local_x > -dx / 2.0) & (local_x < dx / 2.0) &
(local_y > -w / 2.0) & (local_y < w / 2.0); (local_y > -dy / 2.0) & (local_y < dy / 2.0);
return in_flag; return in_flag;
} }
...@@ -52,7 +50,7 @@ __global__ void points_in_boxes_kernel(int batch_size, int boxes_num, ...@@ -52,7 +50,7 @@ __global__ void points_in_boxes_kernel(int batch_size, int boxes_num,
int pts_num, const float *boxes, int pts_num, const float *boxes,
const float *pts, const float *pts,
int *box_idx_of_points) { int *box_idx_of_points) {
// params boxes: (B, N, 7) [x, y, z, w, l, h, rz] in LiDAR coordinate, z is // params boxes: (B, N, 7) [x, y, z, dx, dy, dz, rz] in LiDAR coordinate, z is
// the bottom center, each box DO NOT overlaps params pts: (B, npoints, 3) [x, // the bottom center, each box DO NOT overlaps params pts: (B, npoints, 3) [x,
// y, z] in LiDAR coordinate params boxes_idx_of_points: (B, npoints), default // y, z] in LiDAR coordinate params boxes_idx_of_points: (B, npoints), default
// -1 // -1
...@@ -80,7 +78,7 @@ __global__ void points_in_boxes_batch_kernel(int batch_size, int boxes_num, ...@@ -80,7 +78,7 @@ __global__ void points_in_boxes_batch_kernel(int batch_size, int boxes_num,
int pts_num, const float *boxes, int pts_num, const float *boxes,
const float *pts, const float *pts,
int *box_idx_of_points) { int *box_idx_of_points) {
// params boxes: (B, N, 7) [x, y, z, w, l, h, rz] in LiDAR coordinate, z is // params boxes: (B, N, 7) [x, y, z, dx, dy, dz, rz] in LiDAR coordinate, z is
// the bottom center, each box DO NOT overlaps params pts: (B, npoints, 3) [x, // the bottom center, each box DO NOT overlaps params pts: (B, npoints, 3) [x,
// y, z] in LiDAR coordinate params boxes_idx_of_points: (B, npoints), default // y, z] in LiDAR coordinate params boxes_idx_of_points: (B, npoints), default
// -1 // -1
...@@ -107,7 +105,7 @@ __global__ void points_in_boxes_batch_kernel(int batch_size, int boxes_num, ...@@ -107,7 +105,7 @@ __global__ void points_in_boxes_batch_kernel(int batch_size, int boxes_num,
void points_in_boxes_launcher(int batch_size, int boxes_num, int pts_num, void points_in_boxes_launcher(int batch_size, int boxes_num, int pts_num,
const float *boxes, const float *pts, const float *boxes, const float *pts,
int *box_idx_of_points) { int *box_idx_of_points) {
// params boxes: (B, N, 7) [x, y, z, w, l, h, rz] in LiDAR coordinate, z is // params boxes: (B, N, 7) [x, y, z, dx, dy, dz, rz] in LiDAR coordinate, z is
// the bottom center, each box DO NOT overlaps params pts: (B, npoints, 3) [x, // the bottom center, each box DO NOT overlaps params pts: (B, npoints, 3) [x,
// y, z] in LiDAR coordinate params boxes_idx_of_points: (B, npoints), default // y, z] in LiDAR coordinate params boxes_idx_of_points: (B, npoints), default
// -1 // -1
...@@ -132,7 +130,7 @@ void points_in_boxes_launcher(int batch_size, int boxes_num, int pts_num, ...@@ -132,7 +130,7 @@ void points_in_boxes_launcher(int batch_size, int boxes_num, int pts_num,
void points_in_boxes_batch_launcher(int batch_size, int boxes_num, int pts_num, void points_in_boxes_batch_launcher(int batch_size, int boxes_num, int pts_num,
const float *boxes, const float *pts, const float *boxes, const float *pts,
int *box_idx_of_points) { int *box_idx_of_points) {
// params boxes: (B, N, 7) [x, y, z, w, l, h, rz] in LiDAR coordinate, z is // params boxes: (B, N, 7) [x, y, z, dx, dy, dz, rz] in LiDAR coordinate, z is
// the bottom center, each box params pts: (B, npoints, 3) [x, y, z] in // the bottom center, each box params pts: (B, npoints, 3) [x, y, z] in
// LiDAR coordinate params boxes_idx_of_points: (B, npoints), default -1 // LiDAR coordinate params boxes_idx_of_points: (B, npoints), default -1
cudaError_t err; cudaError_t err;
...@@ -155,7 +153,7 @@ void points_in_boxes_batch_launcher(int batch_size, int boxes_num, int pts_num, ...@@ -155,7 +153,7 @@ void points_in_boxes_batch_launcher(int batch_size, int boxes_num, int pts_num,
int points_in_boxes_gpu(at::Tensor boxes_tensor, at::Tensor pts_tensor, int points_in_boxes_gpu(at::Tensor boxes_tensor, at::Tensor pts_tensor,
at::Tensor box_idx_of_points_tensor) { at::Tensor box_idx_of_points_tensor) {
// params boxes: (B, N, 7) [x, y, z, w, l, h, rz] in LiDAR coordinate, z is // params boxes: (B, N, 7) [x, y, z, dx, dy, dz, rz] in LiDAR coordinate, z is
// the bottom center, each box DO NOT overlaps params pts: (B, npoints, 3) [x, // the bottom center, each box DO NOT overlaps params pts: (B, npoints, 3) [x,
// y, z] in LiDAR coordinate params boxes_idx_of_points: (B, npoints), default // y, z] in LiDAR coordinate params boxes_idx_of_points: (B, npoints), default
// -1 // -1
...@@ -180,7 +178,7 @@ int points_in_boxes_gpu(at::Tensor boxes_tensor, at::Tensor pts_tensor, ...@@ -180,7 +178,7 @@ int points_in_boxes_gpu(at::Tensor boxes_tensor, at::Tensor pts_tensor,
int points_in_boxes_batch(at::Tensor boxes_tensor, at::Tensor pts_tensor, int points_in_boxes_batch(at::Tensor boxes_tensor, at::Tensor pts_tensor,
at::Tensor box_idx_of_points_tensor) { at::Tensor box_idx_of_points_tensor) {
// params boxes: (B, N, 7) [x, y, z, w, l, h, rz] in LiDAR coordinate, z is // params boxes: (B, N, 7) [x, y, z, dx, dy, dz, rz] in LiDAR coordinate, z is
// the bottom center. params pts: (B, npoints, 3) [x, y, z] in LiDAR // the bottom center. params pts: (B, npoints, 3) [x, y, z] in LiDAR
// coordinate params boxes_idx_of_points: (B, npoints), default -1 // coordinate params boxes_idx_of_points: (B, npoints), default -1
......
...@@ -17,9 +17,7 @@ ...@@ -17,9 +17,7 @@
__device__ inline void lidar_to_local_coords(float shift_x, float shift_y, __device__ inline void lidar_to_local_coords(float shift_x, float shift_y,
float rz, float &local_x, float rz, float &local_x,
float &local_y) { float &local_y) {
// should rotate pi/2 + alpha to translate LiDAR to local float cosa = cos(-rz), sina = sin(-rz);
float rot_angle = rz + M_PI / 2;
float cosa = cos(rot_angle), sina = sin(rot_angle);
local_x = shift_x * cosa + shift_y * (-sina); local_x = shift_x * cosa + shift_y * (-sina);
local_y = shift_x * sina + shift_y * cosa; local_y = shift_x * sina + shift_y * cosa;
} }
...@@ -27,17 +25,17 @@ __device__ inline void lidar_to_local_coords(float shift_x, float shift_y, ...@@ -27,17 +25,17 @@ __device__ inline void lidar_to_local_coords(float shift_x, float shift_y,
__device__ inline int check_pt_in_box3d(const float *pt, const float *box3d, __device__ inline int check_pt_in_box3d(const float *pt, const float *box3d,
float &local_x, float &local_y) { float &local_x, float &local_y) {
// param pt: (x, y, z) // param pt: (x, y, z)
// param box3d: (cx, cy, cz, w, l, h, rz) in LiDAR coordinate, cz in the // param box3d: (cx, cy, cz, dx, dy, dz, rz) in LiDAR coordinate, cz in the
// bottom center // bottom center
float x = pt[0], y = pt[1], z = pt[2]; float x = pt[0], y = pt[1], z = pt[2];
float cx = box3d[0], cy = box3d[1], cz = box3d[2]; float cx = box3d[0], cy = box3d[1], cz = box3d[2];
float w = box3d[3], l = box3d[4], h = box3d[5], rz = box3d[6]; float dx = box3d[3], dy = box3d[4], dz = box3d[5], rz = box3d[6];
cz += h / 2.0; // shift to the center since cz in box3d is the bottom center cz += dz / 2.0; // shift to the center since cz in box3d is the bottom center
if (fabsf(z - cz) > h / 2.0) return 0; if (fabsf(z - cz) > dz / 2.0) return 0;
lidar_to_local_coords(x - cx, y - cy, rz, local_x, local_y); lidar_to_local_coords(x - cx, y - cy, rz, local_x, local_y);
float in_flag = (local_x > -l / 2.0) & (local_x < l / 2.0) & float in_flag = (local_x > -dx / 2.0) & (local_x < dx / 2.0) &
(local_y > -w / 2.0) & (local_y < w / 2.0); (local_y > -dy / 2.0) & (local_y < dy / 2.0);
return in_flag; return in_flag;
} }
...@@ -45,9 +43,9 @@ __global__ void generate_pts_mask_for_box3d(int boxes_num, int pts_num, ...@@ -45,9 +43,9 @@ __global__ void generate_pts_mask_for_box3d(int boxes_num, int pts_num,
int out_x, int out_y, int out_z, int out_x, int out_y, int out_z,
const float *rois, const float *pts, const float *rois, const float *pts,
int *pts_mask) { int *pts_mask) {
// params rois: (N, 7) [x, y, z, w, l, h, rz] in LiDAR coordinate // params rois: (N, 7) [x, y, z, dx, dy, dz, rz] in LiDAR coordinate
// params pts: (npoints, 3) [x, y, z] // params pts: (npoints, 3) [x, y, z]
// params pts_mask: (N, npoints): -1 means point doesnot in this box, // params pts_mask: (N, npoints): -1 means point does not in this box,
// otherwise: encode (x_idxs, y_idxs, z_idxs) by binary bit // otherwise: encode (x_idxs, y_idxs, z_idxs) by binary bit
int pt_idx = blockIdx.x * blockDim.x + threadIdx.x; int pt_idx = blockIdx.x * blockDim.x + threadIdx.x;
int box_idx = blockIdx.y; int box_idx = blockIdx.y;
...@@ -63,14 +61,14 @@ __global__ void generate_pts_mask_for_box3d(int boxes_num, int pts_num, ...@@ -63,14 +61,14 @@ __global__ void generate_pts_mask_for_box3d(int boxes_num, int pts_num,
pts_mask[0] = -1; pts_mask[0] = -1;
if (cur_in_flag > 0) { if (cur_in_flag > 0) {
float local_z = pts[2] - rois[2]; float local_z = pts[2] - rois[2];
float w = rois[3], l = rois[4], h = rois[5]; float dx = rois[3], dy = rois[4], dz = rois[5];
float x_res = l / out_x; float x_res = dx / out_x;
float y_res = w / out_y; float y_res = dy / out_y;
float z_res = h / out_z; float z_res = dz / out_z;
unsigned int x_idx = int((local_x + l / 2) / x_res); unsigned int x_idx = int((local_x + dx / 2) / x_res);
unsigned int y_idx = int((local_y + w / 2) / y_res); unsigned int y_idx = int((local_y + dy / 2) / y_res);
unsigned int z_idx = int(local_z / z_res); unsigned int z_idx = int(local_z / z_res);
x_idx = min(max(x_idx, 0), out_x - 1); x_idx = min(max(x_idx, 0), out_x - 1);
...@@ -231,7 +229,7 @@ void roiaware_pool3d_launcher(int boxes_num, int pts_num, int channels, ...@@ -231,7 +229,7 @@ void roiaware_pool3d_launcher(int boxes_num, int pts_num, int channels,
const float *pts_feature, int *argmax, const float *pts_feature, int *argmax,
int *pts_idx_of_voxels, float *pooled_features, int *pts_idx_of_voxels, float *pooled_features,
int pool_method) { int pool_method) {
// params rois: (N, 7) [x, y, z, w, l, h, rz] in LiDAR coordinate // params rois: (N, 7) [x, y, z, dx, dy, dz, rz] in LiDAR coordinate
// params pts: (npoints, 3) [x, y, z] in LiDAR coordinate // params pts: (npoints, 3) [x, y, z] in LiDAR coordinate
// params pts_feature: (npoints, C) // params pts_feature: (npoints, C)
// params argmax: (N, out_x, out_y, out_z, C) // params argmax: (N, out_x, out_y, out_z, C)
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import math
import numpy as np import numpy as np
import os import os
import pytest import pytest
import tempfile import tempfile
import torch import torch
from mmdet3d.core.bbox import LiDARInstance3DBoxes from mmdet3d.core.bbox import LiDARInstance3DBoxes, limit_period
from mmdet3d.datasets import KittiDataset from mmdet3d.datasets import KittiDataset
...@@ -113,6 +114,7 @@ def test_getitem(): ...@@ -113,6 +114,7 @@ def test_getitem():
type='ObjectSample', type='ObjectSample',
db_sampler=dict( db_sampler=dict(
data_root='tests/data/kitti/', data_root='tests/data/kitti/',
# in coordinate system refactor, this test file is modified
info_path='tests/data/kitti/kitti_dbinfos_train.pkl', info_path='tests/data/kitti/kitti_dbinfos_train.pkl',
rate=1.0, rate=1.0,
prepare=dict( prepare=dict(
...@@ -151,8 +153,29 @@ def test_getitem(): ...@@ -151,8 +153,29 @@ def test_getitem():
gt_bboxes_3d = data['gt_bboxes_3d']._data gt_bboxes_3d = data['gt_bboxes_3d']._data
gt_labels_3d = data['gt_labels_3d']._data gt_labels_3d = data['gt_labels_3d']._data
expected_gt_bboxes_3d = torch.tensor( expected_gt_bboxes_3d = torch.tensor(
[[9.5081, -5.2269, -1.1370, 0.4915, 1.2288, 1.9353, -2.7136]]) [[9.5081, -5.2269, -1.1370, 1.2288, 0.4915, 1.9353, 1.9988]])
expected_gt_labels_3d = torch.tensor([0]) expected_gt_labels_3d = torch.tensor([0])
rot_matrix = data['img_metas']._data['pcd_rotation']
rot_angle = data['img_metas']._data['pcd_rotation_angle']
horizontal_flip = data['img_metas']._data['pcd_horizontal_flip']
vertical_flip = data['img_metas']._data['pcd_vertical_flip']
expected_rot_matrix = torch.tensor([[0.8018, 0.5976, 0.0000],
[-0.5976, 0.8018, 0.0000],
[0.0000, 0.0000, 1.0000]])
expected_rot_angle = 0.6404654291602163
noise_angle = 0.20247319
assert torch.allclose(expected_rot_matrix, rot_matrix, atol=1e-4)
assert math.isclose(expected_rot_angle, rot_angle, abs_tol=1e-4)
assert horizontal_flip is True
assert vertical_flip is False
# after coord system refactor
expected_gt_bboxes_3d[:, :3] = \
expected_gt_bboxes_3d[:, :3] @ rot_matrix @ rot_matrix
expected_gt_bboxes_3d[:, -1:] = -np.pi - expected_gt_bboxes_3d[:, -1:] \
+ 2 * rot_angle - 2 * noise_angle
expected_gt_bboxes_3d[:, -1:] = limit_period(
expected_gt_bboxes_3d[:, -1:], period=np.pi * 2)
assert points.shape == (780, 4) assert points.shape == (780, 4)
assert torch.allclose( assert torch.allclose(
gt_bboxes_3d.tensor, expected_gt_bboxes_3d, atol=1e-4) gt_bboxes_3d.tensor, expected_gt_bboxes_3d, atol=1e-4)
...@@ -346,9 +369,10 @@ def test_format_results(): ...@@ -346,9 +369,10 @@ def test_format_results():
pipeline, modality, split = _generate_kitti_dataset_config() pipeline, modality, split = _generate_kitti_dataset_config()
kitti_dataset = KittiDataset(data_root, ann_file, split, pts_prefix, kitti_dataset = KittiDataset(data_root, ann_file, split, pts_prefix,
pipeline, classes, modality) pipeline, classes, modality)
# coord system refactor
boxes_3d = LiDARInstance3DBoxes( boxes_3d = LiDARInstance3DBoxes(
torch.tensor( torch.tensor(
[[8.7314, -1.8559, -1.5997, 0.4800, 1.2000, 1.8900, 0.0100]])) [[8.7314, -1.8559, -1.5997, 1.2000, 0.4800, 1.8900, -1.5808]]))
labels_3d = torch.tensor([ labels_3d = torch.tensor([
0, 0,
]) ])
...@@ -359,21 +383,23 @@ def test_format_results(): ...@@ -359,21 +383,23 @@ def test_format_results():
expected_name = np.array(['Pedestrian']) expected_name = np.array(['Pedestrian'])
expected_truncated = np.array([0.]) expected_truncated = np.array([0.])
expected_occluded = np.array([0]) expected_occluded = np.array([0])
expected_alpha = np.array([-3.3410306]) # coord sys refactor
expected_alpha = np.array(-3.3410306 + np.pi)
expected_bbox = np.array([[710.443, 144.00221, 820.29114, 307.58667]]) expected_bbox = np.array([[710.443, 144.00221, 820.29114, 307.58667]])
expected_dimensions = np.array([[1.2, 1.89, 0.48]]) expected_dimensions = np.array([[1.2, 1.89, 0.48]])
expected_location = np.array([[1.8399826, 1.4700007, 8.410018]]) expected_location = np.array([[1.8399826, 1.4700007, 8.410018]])
expected_rotation_y = np.array([-3.1315928]) expected_rotation_y = np.array([0.0100])
expected_score = np.array([0.5]) expected_score = np.array([0.5])
expected_sample_idx = np.array([0]) expected_sample_idx = np.array([0])
assert np.all(result_files[0]['name'] == expected_name) assert np.all(result_files[0]['name'] == expected_name)
assert np.allclose(result_files[0]['truncated'], expected_truncated) assert np.allclose(result_files[0]['truncated'], expected_truncated)
assert np.all(result_files[0]['occluded'] == expected_occluded) assert np.all(result_files[0]['occluded'] == expected_occluded)
assert np.allclose(result_files[0]['alpha'], expected_alpha) assert np.allclose(result_files[0]['alpha'], expected_alpha, 1e-3)
assert np.allclose(result_files[0]['bbox'], expected_bbox) assert np.allclose(result_files[0]['bbox'], expected_bbox)
assert np.allclose(result_files[0]['dimensions'], expected_dimensions) assert np.allclose(result_files[0]['dimensions'], expected_dimensions)
assert np.allclose(result_files[0]['location'], expected_location) assert np.allclose(result_files[0]['location'], expected_location)
assert np.allclose(result_files[0]['rotation_y'], expected_rotation_y) assert np.allclose(result_files[0]['rotation_y'], expected_rotation_y,
1e-3)
assert np.allclose(result_files[0]['score'], expected_score) assert np.allclose(result_files[0]['score'], expected_score)
assert np.allclose(result_files[0]['sample_idx'], expected_sample_idx) assert np.allclose(result_files[0]['sample_idx'], expected_sample_idx)
tmp_dir.cleanup() tmp_dir.cleanup()
...@@ -386,7 +412,7 @@ def test_bbox2result_kitti(): ...@@ -386,7 +412,7 @@ def test_bbox2result_kitti():
pipeline, classes, modality) pipeline, classes, modality)
boxes_3d = LiDARInstance3DBoxes( boxes_3d = LiDARInstance3DBoxes(
torch.tensor( torch.tensor(
[[8.7314, -1.8559, -1.5997, 0.4800, 1.2000, 1.8900, 0.0100]])) [[8.7314, -1.8559, -1.5997, 1.2000, 0.4800, 1.8900, -1.5808]]))
labels_3d = torch.tensor([ labels_3d = torch.tensor([
0, 0,
]) ])
...@@ -400,10 +426,11 @@ def test_bbox2result_kitti(): ...@@ -400,10 +426,11 @@ def test_bbox2result_kitti():
expected_file_path = os.path.join(temp_kitti_result_dir, '000000.txt') expected_file_path = os.path.join(temp_kitti_result_dir, '000000.txt')
expected_name = np.array(['Pedestrian']) expected_name = np.array(['Pedestrian'])
expected_dimensions = np.array([1.2000, 1.8900, 0.4800]) expected_dimensions = np.array([1.2000, 1.8900, 0.4800])
expected_rotation_y = np.array([0.0100]) - np.pi # coord system refactor (reverse sign)
expected_rotation_y = 0.0100
expected_score = np.array([0.5]) expected_score = np.array([0.5])
assert np.all(det_annos[0]['name'] == expected_name) assert np.all(det_annos[0]['name'] == expected_name)
assert np.allclose(det_annos[0]['rotation_y'], expected_rotation_y) assert np.allclose(det_annos[0]['rotation_y'], expected_rotation_y, 1e-3)
assert np.allclose(det_annos[0]['score'], expected_score) assert np.allclose(det_annos[0]['score'], expected_score)
assert np.allclose(det_annos[0]['dimensions'], expected_dimensions) assert np.allclose(det_annos[0]['dimensions'], expected_dimensions)
assert os.path.exists(expected_file_path) assert os.path.exists(expected_file_path)
......
...@@ -4,6 +4,7 @@ import numpy as np ...@@ -4,6 +4,7 @@ import numpy as np
import tempfile import tempfile
import torch import torch
from mmdet3d.core import limit_period
from mmdet3d.datasets import LyftDataset from mmdet3d.datasets import LyftDataset
...@@ -11,6 +12,7 @@ def test_getitem(): ...@@ -11,6 +12,7 @@ def test_getitem():
np.random.seed(0) np.random.seed(0)
torch.manual_seed(0) torch.manual_seed(0)
root_path = './tests/data/lyft' root_path = './tests/data/lyft'
# in coordinate system refactor, this test file is modified
ann_file = './tests/data/lyft/lyft_infos.pkl' ann_file = './tests/data/lyft/lyft_infos.pkl'
class_names = ('car', 'truck', 'bus', 'emergency_vehicle', 'other_vehicle', class_names = ('car', 'truck', 'bus', 'emergency_vehicle', 'other_vehicle',
'motorcycle', 'bicycle', 'pedestrian', 'animal') 'motorcycle', 'bicycle', 'pedestrian', 'animal')
...@@ -49,9 +51,11 @@ def test_getitem(): ...@@ -49,9 +51,11 @@ def test_getitem():
pcd_horizontal_flip = data['img_metas']._data['pcd_horizontal_flip'] pcd_horizontal_flip = data['img_metas']._data['pcd_horizontal_flip']
pcd_scale_factor = data['img_metas']._data['pcd_scale_factor'] pcd_scale_factor = data['img_metas']._data['pcd_scale_factor']
pcd_rotation = data['img_metas']._data['pcd_rotation'] pcd_rotation = data['img_metas']._data['pcd_rotation']
pcd_rotation_angle = data['img_metas']._data['pcd_rotation_angle']
sample_idx = data['img_metas']._data['sample_idx'] sample_idx = data['img_metas']._data['sample_idx']
pcd_rotation_expected = np.array([[0.99869376, -0.05109515, 0.], # coord sys refactor
[0.05109515, 0.99869376, 0.], pcd_rotation_expected = np.array([[0.99869376, 0.05109515, 0.],
[-0.05109515, 0.99869376, 0.],
[0., 0., 1.]]) [0., 0., 1.]])
assert pts_filename == \ assert pts_filename == \
'tests/data/lyft/lidar/host-a017_lidar1_1236118886901125926.bin' 'tests/data/lyft/lidar/host-a017_lidar1_1236118886901125926.bin'
...@@ -82,6 +86,21 @@ def test_getitem(): ...@@ -82,6 +86,21 @@ def test_getitem():
expected_gt_labels = np.array([0, 4, 7]) expected_gt_labels = np.array([0, 4, 7])
original_classes = lyft_dataset.CLASSES original_classes = lyft_dataset.CLASSES
# manually go through pipeline
expected_points[:, :3] = (
(expected_points[:, :3] * torch.tensor([1, -1, 1]))
@ pcd_rotation_expected @ pcd_rotation_expected) * torch.tensor(
[1, -1, 1])
expected_gt_bboxes_3d[:, :3] = (
(expected_gt_bboxes_3d[:, :3] * torch.tensor([1, -1, 1]))
@ pcd_rotation_expected @ pcd_rotation_expected) * torch.tensor(
[1, -1, 1])
expected_gt_bboxes_3d[:, 3:6] = expected_gt_bboxes_3d[:, [4, 3, 5]]
expected_gt_bboxes_3d[:, 6:] = -expected_gt_bboxes_3d[:, 6:] \
- np.pi / 2 - pcd_rotation_angle * 2
expected_gt_bboxes_3d[:, 6:] = limit_period(
expected_gt_bboxes_3d[:, 6:], period=np.pi * 2)
assert torch.allclose(points, expected_points, 1e-2) assert torch.allclose(points, expected_points, 1e-2)
assert torch.allclose(gt_bboxes_3d.tensor, expected_gt_bboxes_3d, 1e-3) assert torch.allclose(gt_bboxes_3d.tensor, expected_gt_bboxes_3d, 1e-3)
assert np.all(gt_labels_3d.numpy() == expected_gt_labels) assert np.all(gt_labels_3d.numpy() == expected_gt_labels)
...@@ -110,8 +129,10 @@ def test_getitem(): ...@@ -110,8 +129,10 @@ def test_getitem():
def test_evaluate(): def test_evaluate():
root_path = './tests/data/lyft' root_path = './tests/data/lyft'
# in coordinate system refactor, this test file is modified
ann_file = './tests/data/lyft/lyft_infos_val.pkl' ann_file = './tests/data/lyft/lyft_infos_val.pkl'
lyft_dataset = LyftDataset(ann_file, None, root_path) lyft_dataset = LyftDataset(ann_file, None, root_path)
# in coordinate system refactor, this test file is modified
results = mmcv.load('./tests/data/lyft/sample_results.pkl') results = mmcv.load('./tests/data/lyft/sample_results.pkl')
ap_dict = lyft_dataset.evaluate(results, 'bbox') ap_dict = lyft_dataset.evaluate(results, 'bbox')
car_precision = ap_dict['pts_bbox_Lyft/car_AP'] car_precision = ap_dict['pts_bbox_Lyft/car_AP']
...@@ -149,11 +170,11 @@ def test_show(): ...@@ -149,11 +170,11 @@ def test_show():
kitti_dataset = LyftDataset(ann_file, None, root_path) kitti_dataset = LyftDataset(ann_file, None, root_path)
boxes_3d = LiDARInstance3DBoxes( boxes_3d = LiDARInstance3DBoxes(
torch.tensor( torch.tensor(
[[46.1218, -4.6496, -0.9275, 0.5316, 1.4442, 1.7450, 1.1749], [[46.1218, -4.6496, -0.9275, 1.4442, 0.5316, 1.7450, -2.7457],
[33.3189, 0.1981, 0.3136, 0.5656, 1.2301, 1.7985, 1.5723], [33.3189, 0.1981, 0.3136, 1.2301, 0.5656, 1.7985, 3.1401],
[46.1366, -4.6404, -0.9510, 0.5162, 1.6501, 1.7540, 1.3778], [46.1366, -4.6404, -0.9510, 1.6501, 0.5162, 1.7540, -2.9486],
[33.2646, 0.2297, 0.3446, 0.5746, 1.3365, 1.7947, 1.5430], [33.2646, 0.2297, 0.3446, 1.3365, 0.5746, 1.7947, -3.1138],
[58.9079, 16.6272, -1.5829, 1.5656, 3.9313, 1.4899, 1.5505]])) [58.9079, 16.6272, -1.5829, 3.9313, 1.5656, 1.4899, -3.1213]]))
scores_3d = torch.tensor([0.1815, 0.1663, 0.5792, 0.2194, 0.2780]) scores_3d = torch.tensor([0.1815, 0.1663, 0.5792, 0.2194, 0.2780])
labels_3d = torch.tensor([0, 0, 1, 1, 2]) labels_3d = torch.tensor([0, 0, 1, 1, 2])
result = dict(boxes_3d=boxes_3d, scores_3d=scores_3d, labels_3d=labels_3d) result = dict(boxes_3d=boxes_3d, scores_3d=scores_3d, labels_3d=labels_3d)
......
...@@ -8,6 +8,7 @@ from mmdet3d.datasets import SUNRGBDDataset ...@@ -8,6 +8,7 @@ from mmdet3d.datasets import SUNRGBDDataset
def _generate_sunrgbd_dataset_config(): def _generate_sunrgbd_dataset_config():
root_path = './tests/data/sunrgbd' root_path = './tests/data/sunrgbd'
# in coordinate system refactor, this test file is modified
ann_file = './tests/data/sunrgbd/sunrgbd_infos.pkl' ann_file = './tests/data/sunrgbd/sunrgbd_infos.pkl'
class_names = ('bed', 'table', 'sofa', 'chair', 'toilet', 'desk', class_names = ('bed', 'table', 'sofa', 'chair', 'toilet', 'desk',
'dresser', 'night_stand', 'bookshelf', 'bathtub') 'dresser', 'night_stand', 'bookshelf', 'bathtub')
...@@ -120,6 +121,8 @@ def test_getitem(): ...@@ -120,6 +121,8 @@ def test_getitem():
[[0.8308, 4.1168, -1.2035, 2.2493, 1.8444, 1.9245, 1.6486], [[0.8308, 4.1168, -1.2035, 2.2493, 1.8444, 1.9245, 1.6486],
[2.3002, 4.8149, -1.2442, 0.5718, 0.8629, 0.9510, 1.6030], [2.3002, 4.8149, -1.2442, 0.5718, 0.8629, 0.9510, 1.6030],
[-1.1477, 1.8090, -1.1725, 0.6965, 1.5273, 2.0563, 0.0552]]) [-1.1477, 1.8090, -1.1725, 0.6965, 1.5273, 2.0563, 0.0552]])
# coord sys refactor (rotation is correct but yaw has to be reversed)
expected_gt_bboxes_3d[:, 6:] = -expected_gt_bboxes_3d[:, 6:]
expected_gt_labels = np.array([0, 7, 6]) expected_gt_labels = np.array([0, 7, 6])
original_classes = sunrgbd_dataset.CLASSES original_classes = sunrgbd_dataset.CLASSES
......
...@@ -16,6 +16,7 @@ def _generate_waymo_train_dataset_config(): ...@@ -16,6 +16,7 @@ def _generate_waymo_train_dataset_config():
file_client_args = dict(backend='disk') file_client_args = dict(backend='disk')
db_sampler = dict( db_sampler = dict(
data_root=data_root, data_root=data_root,
# in coordinate system refactor, this test file is modified
info_path=data_root + 'waymo_dbinfos_train.pkl', info_path=data_root + 'waymo_dbinfos_train.pkl',
rate=1.0, rate=1.0,
prepare=dict( prepare=dict(
...@@ -114,7 +115,7 @@ def test_getitem(): ...@@ -114,7 +115,7 @@ def test_getitem():
gt_bboxes_3d = data['gt_bboxes_3d']._data gt_bboxes_3d = data['gt_bboxes_3d']._data
gt_labels_3d = data['gt_labels_3d']._data gt_labels_3d = data['gt_labels_3d']._data
expected_gt_bboxes_3d = torch.tensor( expected_gt_bboxes_3d = torch.tensor(
[[31.4750, -4.5690, 2.1857, 2.3519, 6.0931, 3.1756, -1.2895]]) [[31.8048, -0.1002, 2.1857, 6.0931, 2.3519, 3.1756, -0.1403]])
expected_gt_labels_3d = torch.tensor([0]) expected_gt_labels_3d = torch.tensor([0])
assert points.shape == (765, 5) assert points.shape == (765, 5)
assert torch.allclose( assert torch.allclose(
...@@ -132,8 +133,8 @@ def test_evaluate(): ...@@ -132,8 +133,8 @@ def test_evaluate():
pipeline, classes, modality) pipeline, classes, modality)
boxes_3d = LiDARInstance3DBoxes( boxes_3d = LiDARInstance3DBoxes(
torch.tensor([[ torch.tensor([[
6.9684e+01, 3.3335e+01, 4.1465e-02, 2.0100e+00, 4.3600e+00, 6.9684e+01, 3.3335e+01, 4.1465e-02, 4.3600e+00, 2.0100e+00,
1.4600e+00, -9.0000e-02 1.4600e+00, 9.0000e-02 - np.pi / 2
]])) ]]))
labels_3d = torch.tensor([0]) labels_3d = torch.tensor([0])
scores_3d = torch.tensor([0.5]) scores_3d = torch.tensor([0.5])
...@@ -150,8 +151,8 @@ def test_evaluate(): ...@@ -150,8 +151,8 @@ def test_evaluate():
metric = ['waymo'] metric = ['waymo']
boxes_3d = LiDARInstance3DBoxes( boxes_3d = LiDARInstance3DBoxes(
torch.tensor([[ torch.tensor([[
6.9684e+01, 3.3335e+01, 4.1465e-02, 2.0100e+00, 4.3600e+00, 6.9684e+01, 3.3335e+01, 4.1465e-02, 4.3600e+00, 2.0100e+00,
1.4600e+00, -9.0000e-02 1.4600e+00, 9.0000e-02 - np.pi / 2
]])) ]]))
labels_3d = torch.tensor([0]) labels_3d = torch.tensor([0])
scores_3d = torch.tensor([0.8]) scores_3d = torch.tensor([0.8])
...@@ -178,11 +179,11 @@ def test_show(): ...@@ -178,11 +179,11 @@ def test_show():
data_root, ann_file, split=split, modality=modality, pipeline=pipeline) data_root, ann_file, split=split, modality=modality, pipeline=pipeline)
boxes_3d = LiDARInstance3DBoxes( boxes_3d = LiDARInstance3DBoxes(
torch.tensor( torch.tensor(
[[46.1218, -4.6496, -0.9275, 0.5316, 1.4442, 1.7450, 1.1749], [[46.1218, -4.6496, -0.9275, 1.4442, 0.5316, 1.7450, 1.1749],
[33.3189, 0.1981, 0.3136, 0.5656, 1.2301, 1.7985, 1.5723], [33.3189, 0.1981, 0.3136, 1.2301, 0.5656, 1.7985, 1.5723],
[46.1366, -4.6404, -0.9510, 0.5162, 1.6501, 1.7540, 1.3778], [46.1366, -4.6404, -0.9510, 1.6501, 0.5162, 1.7540, 1.3778],
[33.2646, 0.2297, 0.3446, 0.5746, 1.3365, 1.7947, 1.5430], [33.2646, 0.2297, 0.3446, 1.3365, 0.5746, 1.7947, 1.5430],
[58.9079, 16.6272, -1.5829, 1.5656, 3.9313, 1.4899, 1.5505]])) [58.9079, 16.6272, -1.5829, 3.9313, 1.5656, 1.4899, 1.5505]]))
scores_3d = torch.tensor([0.1815, 0.1663, 0.5792, 0.2194, 0.2780]) scores_3d = torch.tensor([0.1815, 0.1663, 0.5792, 0.2194, 0.2780])
labels_3d = torch.tensor([0, 0, 1, 1, 2]) labels_3d = torch.tensor([0, 0, 1, 1, 2])
result = dict(boxes_3d=boxes_3d, scores_3d=scores_3d, labels_3d=labels_3d) result = dict(boxes_3d=boxes_3d, scores_3d=scores_3d, labels_3d=labels_3d)
...@@ -231,8 +232,8 @@ def test_format_results(): ...@@ -231,8 +232,8 @@ def test_format_results():
pipeline, classes, modality) pipeline, classes, modality)
boxes_3d = LiDARInstance3DBoxes( boxes_3d = LiDARInstance3DBoxes(
torch.tensor([[ torch.tensor([[
6.9684e+01, 3.3335e+01, 4.1465e-02, 2.0100e+00, 4.3600e+00, 6.9684e+01, 3.3335e+01, 4.1465e-02, 4.3600e+00, 2.0100e+00,
1.4600e+00, -9.0000e-02 1.4600e+00, 9.0000e-02 - np.pi / 2
]])) ]]))
labels_3d = torch.tensor([0]) labels_3d = torch.tensor([0])
scores_3d = torch.tensor([0.5]) scores_3d = torch.tensor([0.5])
...@@ -252,11 +253,11 @@ def test_format_results(): ...@@ -252,11 +253,11 @@ def test_format_results():
assert np.all(result_files[0]['name'] == expected_name) assert np.all(result_files[0]['name'] == expected_name)
assert np.allclose(result_files[0]['truncated'], expected_truncated) assert np.allclose(result_files[0]['truncated'], expected_truncated)
assert np.all(result_files[0]['occluded'] == expected_occluded) assert np.all(result_files[0]['occluded'] == expected_occluded)
assert np.allclose(result_files[0]['alpha'], expected_alpha) assert np.allclose(result_files[0]['bbox'], expected_bbox, 1e-3)
assert np.allclose(result_files[0]['bbox'], expected_bbox)
assert np.allclose(result_files[0]['dimensions'], expected_dimensions) assert np.allclose(result_files[0]['dimensions'], expected_dimensions)
assert np.allclose(result_files[0]['location'], expected_location) assert np.allclose(result_files[0]['location'], expected_location)
assert np.allclose(result_files[0]['rotation_y'], expected_rotation_y) assert np.allclose(result_files[0]['rotation_y'], expected_rotation_y)
assert np.allclose(result_files[0]['score'], expected_score) assert np.allclose(result_files[0]['score'], expected_score)
assert np.allclose(result_files[0]['sample_idx'], expected_sample_idx) assert np.allclose(result_files[0]['sample_idx'], expected_sample_idx)
assert np.allclose(result_files[0]['alpha'], expected_alpha)
tmp_dir.cleanup() tmp_dir.cleanup()
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