pmneila / PyMCubes

Marching cubes (and related tools) for Python
BSD 3-Clause "New" or "Revised" License
692 stars 87 forks source link

Vertices with no value #20

Closed luigui2906 closed 4 years ago

luigui2906 commented 5 years ago

Hi,

I discovered the marching cubes algorithm recently and I am trying to use it for surface reconstruction on outdoor environments from lidar. For this, I am calculating a Truncated Signed Distance Field (TSDF) that I send to the marching cubes. However, I don't find a way to assign a neutral value (like a NULL) to cubes that are far from my TSDF to avoid errors in my reconstruction, the problem is that since I am reconstructing a scene scanned from Lidar, I don't have a completely closed scanned object, so when I assign the values to further voxels I make mistakes on the reconstruction since I am propagating the SDF after the borders of my surface.

Hope I explained correctly my problem, don't hesitate to ask if you need more details. Thanks for your help and have a nice day,

Luis

pmneila commented 5 years ago

Hi,

If I understood correctly, you have a TSDF and you want to ignore regions that are "far from your TSDF" (I understand you mean that they are far from the zero value of the TSDF). The marching cubes algorithm only cares about regions where the TSDF is around 0 (more specifically, regions where the TSDF changes sign), and it should automatically ignore regions far away from the zero value, which are always positive or negative.

Does this answer your question? Otherwise, you might want to send me a minimal working example that shows a small TSDF with areas you want to ignore.

jeongjoonpark commented 4 years ago

Hi pmneila, I am not the author but would like to add in his description. In KinectFusion, the majority of voxels have NULL value because you don't know if those voxels should have negative or positive SDF. So if there is no option to set a NULL value in your program, I need to assign either a positive or negative value for such a voxel, which will lead to a false surface when there is a sign change. (Because Marching cubes look for sign changes regardless of whether the SDF is around zero or not.) Hope this helps.

luigui2906 commented 4 years ago

Yep, that was exactly what I ment

pmneila commented 4 years ago

Hi @jeongjoonpark and @luigui2906,

That makes complete sense, thank you for clarifying this. How are you representing the NULL values? It think PyMCubes works as you expect when you use NaN to indicate these NULL voxels (in Python you can use np.nan for that). For example, this code works for me:

import numpy as np
import mcubes

coords = np.mgrid[:100, :100, :100] / 100.0
u = (coords[0] - 0.5)**2 + (coords[1] - 0.5)**2 + (coords[2] - 0.5)**2 - 0.4**2

# Set a few locations with NaN.
u[u>0.1] = np.nan
u[u<-0.1] = np.nan

vertices, triangles = mcubes.marching_cubes(u, 0)
mcubes.export_obj(vertices, triangles, "sphere.obj")

This code builds a sphere ignoring the NaN regions. Does this solve your problem?

jeongjoonpark commented 4 years ago

Yes this seems to solve the problem!