isl-org / isl-org/Open3D

Struggling to create a suitable watertight mesh using Open3D from point cloud data

Open
#5,699 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
14k
Forks
2.6k
Avg merge
5d 18h
Merged PRs (30d)
6

Description

### Discussed in https://github.com/isl-org/Open3D/discussions/3913

Originally posted by **conorssmith** August 12, 2021
Hi there, I am trying to create a watertight mesh out of point cloud representing organ contour data from cone beam CT images. My goal is to take two meshes and calculate the volume of intersection between the two of them.

I have tried using each of the methods shown [here](http://www.open3d.org/docs/latest/tutorial/Advanced/surface_reconstruction.html)

### Poisson Reconstruction

```
point_cloud = np.genfromtxt('ct_prostate_contour_data.csv', delimiter=',')
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(point_cloud)
pcd.compute_convex_hull()
pcd.estimate_normals()
pcd.orient_normals_consistent_tangent_plane(10)

mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=10, width=0, scale=20, linear_fit=True)[0]
mesh.compute_vertex_normals()
mesh.paint_uniform_color([0.5, 0.5, 0.5])
mesh.remove_degenerate_triangles()
o3d.visualization.draw_geometries([pcd, mesh], mesh_show_back_face=True)
```

While this method seemingly leads to a watertight mesh to my eye, the result of mesh.is_watertight() is False, however for the Bladder data it returns True. Furthermore, the algorithm extends the mesh above and below the vertical limits of the data. Wile this isn't a deal breaking issue if there were a way to minimize it that would be great.

![Poisson Mesh](https://user-images.githubusercontent.com/88810617/129304982-e81b230a-ea7f-43be-ba71-df7418e2df8c.JPG)

### Ball Pivoting

```
point_cloud = np.genfromtxt('ct_prostate_contour_data.csv', delimiter=',')
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(point_cloud)
pcd.compute_convex_hull()
pcd.estimate_normals()
pcd.orient_normals_consistent_tangent_plane(30)

distances = pcd.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
radii = [0.1*avg_dist, 0.5*avg_dist, 1*avg_dist, 2*avg_dist]
r = o3d.utility.DoubleVector(radii)
rec_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(pcd, r)
o3d.visualization.draw_geometries([pcd, rec_mesh], mesh_show_back_face=True)
```
This would be my preferred method if I were able to fill the holes as it simply connects vertices without interpolation.

![Ball Pivoting](https://user-images.githubusercontent.com/88810617/129305723-240adc9b-c43b-4f02-bfaf-dc22cd1dc373.JPG)

### Alpha Shapes
```
point_cloud = np.genfromtxt('ct_prostate_contour_data.csv', delimiter=',')
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(point_cloud)
alpha = 8
tetra_mesh, pt_map = o3d.geometry.TetraMesh.create_from_point_cloud(pcd)
mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd, alpha, tetra_mesh, pt_map)
mesh.compute_vertex_normals()
mesh.paint_uniform_color([0.5, 0.5, 0.5])
mesh.remove_degenerate_triangles()
o3d.visualization.draw_geometries([pcd, mesh])
```

The results from this are similar to ball pivoting but worse.

![Alpha Shapes](https://user-images.githubusercontent.com/88810617/129306147-9797b45a-4295-4dbb-8f43-87cab2b55a6b.JPG)

[ct_prostate_contour_data.csv](https://github.com/isl-org/Open3D/files/6979880/ct_prostate_contour_data.csv)
[ct_rectum_contour_data.csv](https://github.com/isl-org/Open3D/files/6979881/ct_rectum_contour_data.csv)
[ct_bladder_contour_data.csv](https://github.com/isl-org/Open3D/files/6979882/ct_bladder_contour_data.csv)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.