gradslam/gradslam

Numpy array of voxels to points.

Closed this issue · 4 comments

Just wondering if there is a way to take a voxel array (such as a ndarray of segmented 3d volume) and convert to a point array.

one example the array would be in a format of a 3d array with each value an intensity (if segmented) this would be a low number but worst case an 8 bit file with 255 segments but 0 classed as empty.

The only other way I could think of doing this was to convert this to a 2d format with four columns x, y, z, intensity (or label) but then not sure I could work out how to then get it into gradslam? I may be missing something obvious.

Hi @Sh4zKh4n,

Are you trying to convert a voxel grid containing 0-255 segmentation values to a gradslam.Pointclouds object? If so, here is a basic snippet for doing so:

import gradslam as gs
import numpy as np

# create basic voxel grid
voxel_grid = np.zeros((10, 10, 10, 1), dtype=np.uint8)
voxel_grid[4:6, 4:6, 4:6] = 100

# convert voxel grid to xyz coordinates and features
nonzero_inds = np.nonzero(voxel_grid)[:-1]
points = torch.tensor(nonzero_inds, dtype=torch.float32).T
features = torch.tensor(voxel_grid[nonzero_inds])

# construct gradslam.Pointclouds object
pointclouds = gs.Pointclouds(points=[points], features=[features])

# visualize
o3d.visualization.draw_geometries([pointclouds.open3d(0)])

If you want the points to be colored, you can map the segmentation values to rgb values, and pass those as the colors argument:

colors = features.repeat(1, 3)
pointclouds = gs.Pointclouds(points=[points], colors=[colors])

Hi @saryazdi that's exactly what I needed to get going.

I just now have to work out how to do this for a giant array (I have been using Dask and the zarr with a group (6) of big numpy arrays of micro CT with shapes of around (10367, 2050, 2050). I wanted to find a way to use some of the point cloud based methods but couldn't work out how to convert to point clouds. There is a lot of stuff out there involving point cloud voxelization but not the other way around. Thanks again!

Related to this question, since the new point cloud object is quite big due to the shape (though sparse once I remove the zeros, any thoughts on file storage? I can use zarr but thought I would ask if there was a preferred method to save. I notice there's lots of ways to batch process individual files when using Pytorch but I cant get it round my head how to batch a singular data set that's too big for memory. Sorry if I am being annoying and this should be a separate question? If it does, happy to close and re-open here or wherever you suggest?

This is really helpful.

@Sh4zKh4n Also check out Kaolin's way of converting voxels to pointclouds.

Pointclouds are generally more memory efficient than voxel grids, so memory might not be of concern after converting to pointclouds. For saving the gs.Pointclouds object, you can use open3d:

import open3d as o3d

# this will save the 0-th (batch index) pointcloud as a `.ply` file
o3d.io.write_point_cloud("pointcloud.ply", pointclouds.open3d(0))

Here are other data formats open3d supports for saving pointclouds.

Hey, sorry I thought I had closed this but @saryazdi . Just wanted to say thank you. I know it's a really simple little line but it's usually probably simple things someone tells some one else...not really written down anywhere! So when your trying to work it out your self...it can be a bit of a pain to learn something new and try it in a nother field!