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!
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:
from pyntcloud import PyntCloud
diamond = PyntCloud.from_file("test/data/diamond.ply")
Here is how it looks this example point cloud:
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]
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:
Finally, you can acces the volume of the convex hull as easy as this:
volume = convex_hull.volume
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