Point Structure of Pointcept A Point (point cloud) in Pointcept is a dictionary that contains various properties of a batched point cloud. The property with the following names have a specific definition as follows: - "coord": original coordinate of point cloud; -
| 46 | |
| 47 | |
| 48 | class Point(Dict): |
| 49 | """ |
| 50 | Point Structure of Pointcept |
| 51 | |
| 52 | A Point (point cloud) in Pointcept is a dictionary that contains various properties of |
| 53 | a batched point cloud. The property with the following names have a specific definition |
| 54 | as follows: |
| 55 | |
| 56 | - "coord": original coordinate of point cloud; |
| 57 | - "grid_coord": grid coordinate for specific grid size (related to GridSampling); |
| 58 | Point also support the following optional attributes: |
| 59 | - "offset": if not exist, initialized as batch size is 1; |
| 60 | - "batch": if not exist, initialized as batch size is 1; |
| 61 | - "feat": feature of point cloud, default input of model; |
| 62 | - "grid_size": Grid size of point cloud (related to GridSampling); |
| 63 | (related to Serialization) |
| 64 | - "serialized_depth": depth of serialization, 2 ** depth * grid_size describe the maximum of point cloud range; |
| 65 | - "serialized_code": a list of serialization codes; |
| 66 | - "serialized_order": a list of serialization order determined by code; |
| 67 | - "serialized_inverse": a list of inverse mapping determined by code; |
| 68 | (related to Sparsify: SpConv) |
| 69 | - "sparse_shape": Sparse shape for Sparse Conv Tensor; |
| 70 | - "sparse_conv_feat": SparseConvTensor init with information provide by Point; |
| 71 | """ |
| 72 | |
| 73 | def __init__(self, *args, **kwargs): |
| 74 | super().__init__(*args, **kwargs) |
| 75 | # If one of "offset" or "batch" do not exist, generate by the existing one |
| 76 | if "batch" not in self.keys() and "offset" in self.keys(): |
| 77 | self["batch"] = offset2batch(self.offset) |
| 78 | elif "offset" not in self.keys() and "batch" in self.keys(): |
| 79 | self["offset"] = batch2offset(self.batch) |
| 80 | |
| 81 | def serialization(self, order="z", depth=None, shuffle_orders=False): |
| 82 | """ |
| 83 | Point Cloud Serialization |
| 84 | |
| 85 | relay on ["grid_coord" or "coord" + "grid_size", "batch", "feat"] |
| 86 | """ |
| 87 | assert "batch" in self.keys() |
| 88 | if "grid_coord" not in self.keys(): |
| 89 | # if you don't want to operate GridSampling in data augmentation, |
| 90 | # please add the following augmentation into your pipline: |
| 91 | # dict(type="Copy", keys_dict={"grid_size": 0.01}), |
| 92 | # (adjust `grid_size` to what your want) |
| 93 | assert {"grid_size", "coord"}.issubset(self.keys()) |
| 94 | self["grid_coord"] = torch.div( |
| 95 | self.coord - self.coord.min(0)[0], self.grid_size, rounding_mode="trunc" |
| 96 | ).int() |
| 97 | |
| 98 | if depth is None: |
| 99 | # Adaptive measure the depth of serialization cube (length = 2 ^ depth) |
| 100 | depth = int(self.grid_coord.max()).bit_length() |
| 101 | self["serialized_depth"] = depth |
| 102 | # Maximum bit length for serialization code is 63 (int64) |
| 103 | assert depth * 3 + len(self.offset).bit_length() <= 63 |
| 104 | # Here we follow OCNN and set the depth limitation to 16 (48bit) for the point position. |
| 105 | # Although depth is limited to less than 16, we can encode a 655.36^3 (2^16 * 0.01) meter^3 |