bev-project/mmdet3d/datasets/pipelines/loading_utils.py

108 lines
3.7 KiB
Python
Raw Permalink Normal View History

2022-06-03 12:21:18 +08:00
import os
import numpy as np
import torch
__all__ = ["load_augmented_point_cloud", "reduce_LiDAR_beams"]
def load_augmented_point_cloud(path, virtual=False, reduce_beams=32):
# NOTE: following Tianwei's implementation, it is hard coded for nuScenes
points = np.fromfile(path, dtype=np.float32).reshape(-1, 5)
# NOTE: path definition different from Tianwei's implementation.
tokens = path.split("/")
vp_dir = "_VIRTUAL" if reduce_beams == 32 else f"_VIRTUAL_{reduce_beams}BEAMS"
seg_path = os.path.join(
*tokens[:-3],
"virtual_points",
tokens[-3],
tokens[-2] + vp_dir,
tokens[-1] + ".pkl.npy",
)
assert os.path.exists(seg_path)
data_dict = np.load(seg_path, allow_pickle=True).item()
virtual_points1 = data_dict["real_points"]
# NOTE: add zero reflectance to virtual points instead of removing them from real points
virtual_points2 = np.concatenate(
[
data_dict["virtual_points"][:, :3],
np.zeros([data_dict["virtual_points"].shape[0], 1]),
data_dict["virtual_points"][:, 3:],
],
axis=-1,
)
points = np.concatenate(
[
points,
np.ones([points.shape[0], virtual_points1.shape[1] - points.shape[1] + 1]),
],
axis=1,
)
virtual_points1 = np.concatenate(
[virtual_points1, np.zeros([virtual_points1.shape[0], 1])], axis=1
)
# note: this part is different from Tianwei's implementation, we don't have duplicate foreground real points.
if len(data_dict["real_points_indice"]) > 0:
points[data_dict["real_points_indice"]] = virtual_points1
if virtual:
virtual_points2 = np.concatenate(
[virtual_points2, -1 * np.ones([virtual_points2.shape[0], 1])], axis=1
)
points = np.concatenate([points, virtual_points2], axis=0).astype(np.float32)
return points
def reduce_LiDAR_beams(pts, reduce_beams_to=32):
# print(pts.size())
if isinstance(pts, np.ndarray):
pts = torch.from_numpy(pts)
radius = torch.sqrt(pts[:, 0].pow(2) + pts[:, 1].pow(2) + pts[:, 2].pow(2))
sine_theta = pts[:, 2] / radius
# [-pi/2, pi/2]
theta = torch.asin(sine_theta)
phi = torch.atan2(pts[:, 1], pts[:, 0])
top_ang = 0.1862
down_ang = -0.5353
beam_range = torch.zeros(32)
beam_range[0] = top_ang
beam_range[31] = down_ang
for i in range(1, 31):
beam_range[i] = beam_range[i - 1] - 0.023275
# beam_range = [1, 0.18, 0.15, 0.13, 0.11, 0.085, 0.065, 0.03, 0.01, -0.01, -0.03, -0.055, -0.08, -0.105, -0.13, -0.155, -0.18, -0.205, -0.228, -0.251, -0.275,
# -0.295, -0.32, -0.34, -0.36, -0.38, -0.40, -0.425, -0.45, -0.47, -0.49, -0.52, -0.54]
num_pts, _ = pts.size()
mask = torch.zeros(num_pts)
if reduce_beams_to == 16:
for id in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]:
beam_mask = (theta < (beam_range[id - 1] - 0.012)) * (
theta > (beam_range[id] - 0.012)
)
mask = mask + beam_mask
mask = mask.bool()
elif reduce_beams_to == 4:
for id in [7, 9, 11, 13]:
beam_mask = (theta < (beam_range[id - 1] - 0.012)) * (
theta > (beam_range[id] - 0.012)
)
mask = mask + beam_mask
mask = mask.bool()
# [?] pick the 14th beam
elif reduce_beams_to == 1:
chosen_beam_id = 9
mask = (theta < (beam_range[chosen_beam_id - 1] - 0.012)) * (
theta > (beam_range[chosen_beam_id] - 0.012)
)
else:
raise NotImplementedError
# points = copy.copy(pts)
points = pts[mask]
# print(points.size())
return points.numpy()