MCPcopy Create free account
hub / github.com/apple/ml-pointersect / voxel_downsampling

Method voxel_downsampling

pointersect/inference/structures.py:468–588  ·  view source on GitHub ↗

Voxel downsampling uses a voxel grid to uniformly downsample the input point cloud. Procedure: - Points are discretized into voxels. - Each occupied voxel generates exactly one point by averaging all points inside. Args: cell_width:

(
            self,
            cell_width: float,
            sigma: float = 0.5,
            drop_features: bool = True,
            bidx: int = 0,
    )

Source from the content-addressed store, hash-verified

466 return PointCloud(**out_dict)
467
468 def voxel_downsampling(
469 self,
470 cell_width: float,
471 sigma: float = 0.5,
472 drop_features: bool = True,
473 bidx: int = 0,
474 ) -> 'PointCloud':
475 """
476 Voxel downsampling uses a voxel grid to uniformly downsample the input point cloud.
477
478 Procedure:
479 - Points are discretized into voxels.
480 - Each occupied voxel generates exactly one point by averaging all points inside.
481
482 Args:
483 cell_width:
484 the width of each grid cell.
485 If <0, return self (do nothing)
486 sigma:
487 the sigma used in computing the gaussian weight
488
489 Returns:
490 """
491 if cell_width < 0:
492 return self
493
494 print(f'voxel downsampling started, original num points = {self.xyz_w.size(1)}')
495
496 assert self.xyz_w.size(0) == 1
497
498 sigma = sigma * cell_width
499
500 xyz_w = self.extract_valid_attr(
501 arr=self.xyz_w,
502 bidx=bidx,
503 ).unsqueeze(0) # (b=1, n, 3)
504
505 # construct grid
506 grid_to = xyz_w.max(dim=-2, keepdim=True)[0] + 1.e-3 # (b, 1, 3)
507 grid_from = xyz_w.min(dim=-2, keepdim=True)[0] - 1.e-3 # (b, 1, 3)
508 grid_width = grid_to - grid_from # (b, 1, 3)
509 grid_size = torch.ceil(grid_width / cell_width).long() # (b, 1, 3)
510 cell_width = grid_width / grid_size.float() # (b, 1, 3)
511
512 # discretize to cell idx
513 subidxs = torch.floor((xyz_w - grid_from) / cell_width).long() # (b, n, 3)
514 inds = subidxs[..., 2] + \
515 subidxs[..., 1] * grid_size[..., 2] + \
516 subidxs[..., 0] * (grid_size[..., 1] * grid_size[..., 2]) # (b, n)
517
518 # remap ind to unique index (remove unused grid_cells)
519 all_point_clouds = []
520 for b in range(self.xyz_w.size(0)):
521 # xyz_w = self.xyz_w[b, start_idx:]
522 _, idxs, counts = torch.unique(inds[b], return_inverse=True, return_counts=True)
523 # idxs: (n,)
524 # counts: (num_occupied_cells,)
525 num_occupied_cells = counts.size(0)

Callers 4

render_meshFunction · 0.80
render_rgbdFunction · 0.80
render_arkitscenesFunction · 0.80
render_point_cloudFunction · 0.80

Calls 4

extract_valid_attrMethod · 0.95
PointCloudClass · 0.85
sizeMethod · 0.80
catMethod · 0.45

Tested by

no test coverage detected