marian42 / mesh_to_sdf

Calculate signed distance fields for arbitrary meshes
https://pypi.org/project/mesh-to-sdf/
MIT License
967 stars 105 forks source link

Different SDF Samples than DeepSDF. #41

Open philippwulff opened 1 year ago

philippwulff commented 1 year ago

Hi, I looked into this library as an alternative for the mesh2sdf preprocessing pipeline in DeepSDF and I noticed that this library chooses the SDF sample location much closer to the boundary than the algorithm in DeepSDF. Why is that? Is it deliberate and does't this have negative results on training DeepSDF style models, since the sampling locations x,y,z are smaller values and therefore more difficult to learn for a network?

Let me show an example:

Loading a preprocessed shape from DeepSDF and converting a mesh to an SDF via this library:

deepsdf_sdf = "data/SdfSamples/ShapeNetV2/04256520/1a4a8592046253ab5ff61a3a2a0e2484.npz"
deepsdf_mesh = "/mnt/hdd/ShapeNetCore.v2/04256520/1a4a8592046253ab5ff61a3a2a0e2484/models/model_normalized.obj"

samples = np.load(deepsdf_sdf)
neg_samples = samples["neg"]
pos_samples = samples["pos"]
points_dsdf = np.concatenate((neg_samples[:,:3], pos_samples[:,:3]), axis=0)
sdf_dsdf = np.concatenate((neg_samples[:,3], pos_samples[:,3]), axis=0)

mesh = trimesh.load(deepsdf_mesh)
points_py, sdf_py = sample_sdf_near_surface(mesh, number_of_points=500000)

# plotting the SDF values
plt.hist(sdf_dsdf, bins=100, label="DeepSDF")
plt.hist(sdf_py, bins=100, label="mesh_to_sdf")
plt.legend();

Screenshot 2023-01-10 at 23 48 09

As you can see, the SDF values given by this library are much closer to zero than with the DeepSDF tool.

Rendering the SDF values smaller than 0 from mesh_to_sdf: Screenshot 2023-01-10 at 23 48 55

Rendering the SDF values smaller than 0 from DeepSDF's preprocessing pipeline: Screenshot 2023-01-10 at 23 50 00

I looked at the for choosing the sampling locations in this library and in the DeepSDF code and it looked almost identical. I only think, that mesh_to_sdf uses a twice as large variance (even though this difference seems to require much than just x2). I also looked at other examples and what I found is not unique.

philippwulff commented 1 year ago

Update: Scaling the standard deviation in your code used for selecting the sample positions close to the surface by 10 gives me this result:

Screenshot 2023-01-11 at 00 04 20

which is closer to DeepSDF.

alvinsunyixiao commented 10 months ago

I think DeepSDF specifies the noise variance while the parameter in this repo is specified using standard deviation. You should take the square root to compare.

dqj5182 commented 5 months ago

@philippwulff May I ask how you scaled the standard deviation in the code?

philippwulff commented 5 months ago

@dqj5182 It's been a while, but I remember that there Is a line pretty deep down in the source code that you need to modify for that.

dqj5182 commented 5 months ago

@philippwulff Thanks for the reply! Would the code you mentioned be this part?

https://github.com/marian42/mesh_to_sdf/blob/66036a747e82e7129f6afc74c5325d676a322114/mesh_to_sdf/surface_point_cloud.py#L59

philippwulff commented 5 months ago

No, you need to find the code that samples locations. I couldn’t find it just now, but it is there somewhere.

JiaoZixun commented 2 months ago

Have you found the part that affects the sampling position? I have tested some places, and the sampling point is still close to 0