3dtest / projects /CENet /cenet /transforms_3d.py
giantmonkeyTC
mm2
c2ca15f
raw
history blame
3.37 kB
# Copyright (c) OpenMMLab. All rights reserved.
from typing import Sequence
import numpy as np
from mmcv.transforms import BaseTransform
from mmdet3d.registry import TRANSFORMS
@TRANSFORMS.register_module()
class SemkittiRangeView(BaseTransform):
"""Convert Semantickitti point cloud dataset to range image."""
def __init__(self,
H: int = 64,
W: int = 2048,
fov_up: float = 3.0,
fov_down: float = -25.0,
means: Sequence[float] = (11.71279, -0.1023471, 0.4952,
-1.0545, 0.2877),
stds: Sequence[float] = (10.24, 12.295865, 9.4287, 0.8643,
0.1450),
ignore_index: int = 19) -> None:
self.H = H
self.W = W
self.fov_up = fov_up / 180.0 * np.pi
self.fov_down = fov_down / 180.0 * np.pi
self.fov = abs(self.fov_down) + abs(self.fov_up)
self.means = np.array(means, dtype=np.float32)
self.stds = np.array(stds, dtype=np.float32)
self.ignore_index = ignore_index
def transform(self, results: dict) -> dict:
points_numpy = results['points'].numpy()
proj_image = np.full((self.H, self.W, 5), -1, dtype=np.float32)
proj_idx = np.full((self.H, self.W), -1, dtype=np.int64)
# get depth of all points
depth = np.linalg.norm(points_numpy[:, :3], 2, axis=1)
# get angles of all points
yaw = -np.arctan2(points_numpy[:, 1], points_numpy[:, 0])
pitch = np.arcsin(points_numpy[:, 2] / depth)
# get projection in image coords
proj_x = 0.5 * (yaw / np.pi + 1.0)
proj_y = 1.0 - (pitch + abs(self.fov_down)) / self.fov
# scale to image size using angular resolution
proj_x *= self.W
proj_y *= self.H
# round and clamp for use as index
proj_x = np.floor(proj_x)
proj_x = np.minimum(self.W - 1, proj_x)
proj_x = np.maximum(0, proj_x).astype(np.int64)
proj_y = np.floor(proj_y)
proj_y = np.minimum(self.H - 1, proj_y)
proj_y = np.maximum(0, proj_y).astype(np.int64)
results['proj_x'] = proj_x
results['proj_y'] = proj_y
results['unproj_range'] = depth
# order in decreasing depth
indices = np.arange(depth.shape[0])
order = np.argsort(depth)[::-1]
proj_idx[proj_y[order], proj_x[order]] = indices[order]
proj_image[proj_y[order], proj_x[order], 0] = depth[order]
proj_image[proj_y[order], proj_x[order], 1:] = points_numpy[order]
proj_mask = (proj_idx > 0).astype(np.int32)
results['proj_range'] = proj_image[..., 0]
proj_image = (proj_image -
self.means[None, None, :]) / self.stds[None, None, :]
proj_image = proj_image * proj_mask[..., None].astype(np.float32)
results['img'] = proj_image
if 'pts_semantic_mask' in results:
proj_sem_label = np.full((self.H, self.W),
self.ignore_index,
dtype=np.int64)
proj_sem_label[proj_y[order],
proj_x[order]] = results['pts_semantic_mask'][order]
results['gt_semantic_seg'] = proj_sem_label
return results