chaytonmin / Occupancy-MAE

Official implementation of our TIV'23 paper: Occupancy-MAE: Self-supervised Pre-training Large-scale LiDAR Point Clouds with Masked Occupancy Autoencoders
Apache License 2.0
252 stars 18 forks source link

Understanding Range Aware Masking? #28

Open Varatharajan-Raja opened 1 year ago

Varatharajan-Raja commented 1 year ago

Kindly clarify me few questions about the Range aware masking.

  1. How is the distance calculated with voxel coordinates? If I'm right voxel coordinates should have size N x 4 i.e [Batch, z_idx , y_idx ,x_idx] after the voxelization.
  2. Furthermore, where do you have the center of the point cloud scene which you should consider as origin so that you take it as a reference to do a range aware masking? See here

voxel_coords_distance = (voxel_coords[:,2]**2 + voxel_coords[:,3]**2)**0.5

serend1p1ty commented 1 year ago
voxel_coords_distance = (
            ((voxel_coords[:, 2] - self.sparse_shape[1] / 2) * self.voxel_size[1])**2 +
            ((voxel_coords[:, 3] - self.sparse_shape[2] / 2) * self.voxel_size[0])**2)**0.5

I think the above is right code.

Xu2729 commented 11 months ago

Perhaps we should consider the impact of point_cloud_range, and I think this is correct

voxel_coords = (voxel_indices[:, 1:] * voxel_size) + point_cloud_range + (voxel_size * 0.5)    # z, y, x
voxel_coords_distance = (voxel_coords[:,1]**2 + voxel_coords[:,2]**2)**0.5
huixiancheng commented 11 months ago
def __init__():
        self.voxel_size = voxel_size[::-1]
        self.point_cloud_range = point_cloud_range[:3][::-1]

def forward():
        voxel_coords = (voxel_coords[:, 1:] * self.voxel_size) + self.point_cloud_range + (self.voxel_size * 0.5)    # z, y, x
        voxel_coords_distance = (voxel_coords[:,1]**2 + voxel_coords[:,2]**2)**0.5

For all code mentioned above, Like this finally? :sleepy:@serend1p1ty @Xu2729

Xu2729 commented 11 months ago
def __init__():
        self.voxel_size = voxel_size[::-1]
        self.point_cloud_range = point_cloud_range[:3][::-1]

def forward():
        voxel_coords = (voxel_coords[:, 1:] * self.voxel_size) + self.point_cloud_range + (self.voxel_size * 0.5)    # z, y, x
        voxel_coords_distance = (voxel_coords[:,1]**2 + voxel_coords[:,2]**2)**0.5

For all code mentioned above, Like this finally? 😪@serend1p1ty @Xu2729

This looks logically correct, but it will actually cause a TypeError when running. You need to convert these variables to tensors before performing the operation. I solved it using the following code

def forward():
    # ...
    voxel_size_ts = torch.tensor(self.voxel_size[::-1], device=voxel_indices.device)
    point_cloud_range_ts = torch.tensor(list(self.point_cloud_range)[0:3][::-1], device=voxel_indices.device)
    voxel_coords = (voxel_indices[:, 1:] * voxel_size_ts) + point_cloud_range_ts + (voxel_size_ts * 0.5)
    voxel_coords_distance = (voxel_coords[:,1]**2 + voxel_coords[:,2]**2)**0.5
    # ...

I wanted to put voxel_size_ts and point_cloud_range_ts into the __init__ function, but they are tensors on different devices error. I couldn't find a better solution, so I put them in forward function instead.

I print the number of voxels in each range, and it looks correct.

huixiancheng commented 11 months ago

Thx for your kind reply ~! It's help a lot. @Xu2729 I think our code is consistent. :joy: I thought overriding and updating voxel_coords might have problems.

voxel_size = torch.tensor(self.voxel_size[::-1]).to(voxel_coords.device)
point_cloud_range = torch.tensor(self.point_cloud_range[:3][::-1].copy()).to(voxel_coords.device)
voxel_range = (voxel_coords[:, 1:] * voxel_size) + point_cloud_range + (voxel_size * 0.5)    # z, y, x
voxel_coords_distance = (voxel_range[:,1]**2 + voxel_range[:,2]**2)**0.5