daavoo / pyntcloud

pyntcloud is a Python library for working with 3D point clouds.
http://pyntcloud.readthedocs.io
MIT License
1.42k stars 224 forks source link

Convex hull not fitting well to my data #290

Open enied27 opened 4 years ago

enied27 commented 4 years ago

Greetings!

I think my issue is not a bug or a feature request; I am looking for help with a problem for my specific data set and how I am setting up the problem.

I have a point cloud in CSV format (I uploaded it as .xlsx because Github wouldn't let me upload a .csv):

deposit.xlsx

This is (X,Y,Z) data from a scanner that describes a surface of an object.

I can plot it with this code:

import matplotlib.pyplot as plt
import pandas as pd
df=data
df.columns=["X","Y","Z"]
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.viridis, linewidth=0.01)
plt.show()

The plot looks like this: image

As you can see, it is mostly a cone, but there is some rough area near the base. Also, there are small features away from the cone. What I want is the volume of everything that is above the z=0 plane.

I downloaded Pyntcloud after I saw this stack overflow post: https://stackoverflow.com/questions/44997054/point-cloud-to-volume I am following the same procedure.

I use the following code:

from pyntcloud import PyntCloud

deposit = PyntCloud.from_file("deposit.csv")
convex_hull_id = deposit.add_structure("convex_hull")
convex_hull = deposit.structures[convex_hull_id]
deposit.mesh = convex_hull.get_mesh()
deposit.to_file("deposit.ply", also_save=["mesh"])
volume = convex_hull.volume

However, when I do this, I am not getting a mesh of my object. Instead, the system creates a pyramid, with the max height of my object as the vertex. The mesh looks like this: image

By the way, I know the answer to what the volume should be. It should be about 22. Does anyone see what I've overlooked? Do I need a finer mesh to capture the features of my surface?

Thanks,

Eric

daavoo commented 4 years ago

Hola @enied27 ! Thanks for the detailed question.

The Convex Hull is working as expected (https://en.wikipedia.org/wiki/Convex_hull), however it is a very limited algorithm for recovering the triangle mesh and relying on that for computing volume. The shape and distribution of your shared point cloud is just not a good fit for this approximation.

For this kind of data you could either use:

So. In order to use the grid-based approximation you could use PyntCloud only, but for the more elaborated surface reconstruction you would need to use other libraries (which are supported for easy integration with PyntCloud). I will try to post the code for both cases at the end of the day.

imnileshd commented 2 years ago

Hola @enied27 ! Thanks for the detailed question.

The Convex Hull is working as expected (https://en.wikipedia.org/wiki/Convex_hull), however it is a very limited algorithm for recovering the triangle mesh and relying on that for computing volume. The shape and distribution of your shared point cloud is just not a good fit for this approximation.

For this kind of data you could either use:

  • a more elaborated surface reconstruction algorithm (i.e. poisson surface reconstruction)
  • A grid-based approximate estimation of the volume. Assuming that your point cloud has a ~2.5D shape representing a surface (i.e. for some X, Y coordinate, there are not multiple relevant Z values). I think that this is the case of your point cloud.

So. In order to use the grid-based approximation you could use PyntCloud only, but for the more elaborated surface reconstruction you would need to use other libraries (which are supported for easy integration with PyntCloud). I will try to post the code for both cases at the end of the day.

Could you please share the code for this?