I'm using VoxelGenerator.point_to_voxel(), to get the voxelized points. But I fond the return value of coordinates out of range. Did I miss some procedure or wrong understanding the function? Please let me understand, thank you. Here's my code.
import numpy as np
from skimage import transform
from pcdet.models.backbones_3d.spconv_backbone import VoxelBackBone8x
import torch
import torchvision
import spconv
tv = None
try:
import cumm.tensorview as tv
except:
pass
class voxelgenerator():
def __init__(self,vsize_xyz, coors_range_xyz, num_point_features, max_num_points_per_voxel, max_num_voxels):
print(vsize_xyz, coors_range_xyz, num_point_features, max_num_points_per_voxel, max_num_voxels)
try:
from spconv.utils import VoxelGeneratorV2 as VoxelGenerator
self.spconv_ver = 1
except:
try:
from spconv.utils import VoxelGenerator
self.spconv_ver = 1
except:
from spconv.utils import Point2VoxelCPU3d as VoxelGenerator
self.spconv_ver = 2
if self.spconv_ver == 1:
self._voxel_generator = VoxelGenerator(
voxel_size=vsize_xyz,
point_cloud_range=coors_range_xyz,
max_num_points=max_num_points_per_voxel,
max_voxels=max_num_voxels
)
else:
self._voxel_generator = VoxelGenerator(
vsize_xyz=vsize_xyz,
coors_range_xyz=coors_range_xyz,
num_point_features=num_point_features,
max_num_points_per_voxel=max_num_points_per_voxel,
max_num_voxels=max_num_voxels
)
def generate(self, points):
if self.spconv_ver == 1:
voxel_output = self._voxel_generator.generate(points)
if isinstance(voxel_output, dict):
voxels, coordinates, num_points = \
voxel_output['voxels'], voxel_output['coordinates'], voxel_output['num_points_per_voxel']
else:
voxels, coordinates, num_points = voxel_output
else:
assert tv is not None, f"Unexpected error, library: 'cumm' wasn't imported properly."
voxel_output = self._voxel_generator.point_to_voxel(tv.from_numpy(points))
tv_voxels, tv_coordinates, tv_num_points = voxel_output
# make copy with numpy(), since numpy_view() will disappear as soon as the generator is deleted
voxels = tv_voxels.numpy()
coordinates = tv_coordinates.numpy()
num_points = tv_num_points.numpy()
return voxels, coordinates, num_points
def meanVFE(self,voxel_features, voxel_num_points):
points_mean = voxel_features[:, :, :].sum(dim=1, keepdim=False) # Use sum() instead of _sum()
normalizer = torch.clamp_min(voxel_num_points.view(-1, 1), min=1.0).type_as(voxel_features)
points_mean = points_mean / normalizer
return points_mean.contiguous()
voxel_size = dataset_processor_cfg[2].VOXEL_SIZE
points_range = cfg.DATA_CONFIG.POINT_CLOUD_RANGE
num_point_features = cfg.DATA_CONFIG.DATA_AUGMENTOR.AUG_CONFIG_LIST[0].NUM_POINT_FEATURES
max_number_per_voxel = dataset_processor_cfg[2].MAX_POINTS_PER_VOXEL
max_number_of_voxels = dataset_processor_cfg[2].MAX_NUMBER_OF_VOXELS['train']
#grid_size = cfg.MODEL.ROI_HEAD.ROI_GRID_POOL.GRID_SIZE
grid_size = points_range[3:6] - points_range[0:3] / np.array(voxel_size)
grid_size = np.round(grid_size).astype(np.int64)
print(grid_size)
voxel_generator = voxelgenerator(voxel_size, points_range, num_point_features, max_number_per_voxel, max_number_of_voxels)
points = np.fromfile(data_path, dtype=np.float32).reshape(-1, 4)
# only use the points in points range
# print('origin', len(points))
# points = points[(points[:, 0] >= points_range[0]) & (points[:, 0] < points_range[3]) &
# (points[:, 1] >= points_range[1]) & (points[:, 1] < points_range[4]) &
# (points[:, 2] >= points_range[2]) & (points[:, 2] < points_range[5])]
# print('after', len(points))
voxels, coordinates, num_points = voxel_generator.generate(points)
voxels = torch.from_numpy(voxels)
coordinates = torch.from_numpy(coordinates)
num_points = torch.from_numpy(num_points)
# print max of coordinates
print(coordinates.max(0), coordinates.min(0))
mean_voxel = voxel_generator.meanVFE(voxels, num_points)
print(mean_voxel.shape, coordinates.shape, num_points.shape)
# 2. load the voxelbackbone
backbone = VoxelBackBone8x(model_cfg=cfg, input_channels=num_point_features, grid_size=grid_size)
# [batch_idx, z_idx, y_idx, x_idx]
coordinates = torch.cat([torch.zeros_like(coordinates[:, :1]), coordinates], dim=1)
for i in range(len(coordinates)):
coordinates[i, 0] = i
# mean_voxels, coordinates, num_points to cuda
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
torch.cuda.set_device(0)
mean_voxel = mean_voxel.to(0)
coordinates = coordinates.to(0)
num_points = num_points.to(0)
sp_input_res = backbone.get_input_layer_result(voxel_features=mean_voxel, voxel_coords=coordinates,batch_size=1)
And the input parameters of voxelgenerator are [0.05, 0.05, 0.1] [-70.4, -40, -3, 70.4, 40, 1] 4 5 16000, grid size is [1478 840 31]. But the max and min of coordinates are
I'm using
VoxelGenerator.point_to_voxel()
, to get the voxelized points. But I fond the return value of coordinates out of range. Did I miss some procedure or wrong understanding the function? Please let me understand, thank you. Here's my code.And the input parameters of
voxelgenerator
are[0.05, 0.05, 0.1] [-70.4, -40, -3, 70.4, 40, 1] 4 5 16000
, grid size is[1478 840 31]
. But the max and min of coordinates are