Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Point Cloud to Volume [closed]

I have a point cloud in cartesian coordinates. Using python I would like to wrap those points in a mesh and then take a volume of the cloud. The points are distributed throughout the cloud and not just representing the outermost surface. I would like to wrap the outermost surface. Can anyone point me to a library that can help me with this? What functions do you recommend I use to wrap and then calculate the volume?

Thanks for the help in advance!

like image 400
geop Avatar asked Jul 09 '17 13:07

geop


1 Answers

What you need to do is to compute the Convex Hull of your point cloud.

You can do this using https://github.com/daavoo/pyntcloud (contributions are welcome).

Here are the steps:

Load point cloud from file:

from pyntcloud import PyntCloud
diamond = PyntCloud.from_file("test/data/diamond.ply")

Here is how it looks this example point cloud: point cloud

Compute Convex Hull

This uses scipy's wrap of Qhull library:

convex_hull_id = diamond.add_structure("convex_hull")

You can access the convex hull like this:

convex_hull = diamond.structures[convex_hull_id]

Visualize the Convex Hull

You can generate a mesh from the convex hull as follows:

diamond.mesh = convex_hull.get_mesh()

And save the point cloud + mesh to a file (for example ply format) and visualize it in any 3D mesh software (for example Meshlab):

diamond.to_file("diamond_hull.ply", also_save=["mesh"])

Here is the output visualized in meshlab:

mesh

Get volume from Convex Hull

Finally, you can acces the volume of the convex hull as easy as this:

volume = convex_hull.volume

Test with sphere

To test the precision of this approach you can run the following code.

This will generate a point cloud of a sphere (radius 25) and use the convex hull to compute the volume:

from pyntcloud import PyntCloud
from pyntcloud.geometry.models.sphere import create_sphere
cloud = PyntCloud(create_sphere(center=[0, 0, 0], radius=25, n_points=100000))
convex_hull_id = cloud.add_structure("convex_hull")
convex_hull = cloud.structures[convex_hull_id]
print(convex_hull.volume)

Outputs:

65439.21101051165

And because it is a sphere we can actually compute the real volume:

import numpy as np
# google: volume of sphere
print((4/3) * np.pi * (25 ** 3))

Outputs:

65449.84694978735

Whit is pretty close, given that we are working with meters, and we only use 100000 points to approximate the sphere

like image 169
David de la Iglesia Avatar answered Sep 18 '22 02:09

David de la Iglesia