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:
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:
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