jmartinezot commited on
Commit
5a827da
1 Parent(s): a558214

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -0
app.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import open3d as o3d
3
+ import numpy as np
4
+ import pandas as pd
5
+ from PIL import Image
6
+ from gradio.components import File, Slider, Image, Dataframe, Model3D
7
+ import tempfile
8
+
9
+ def point_cloud_to_image(point_cloud):
10
+ # Create Open3D visualization object
11
+ vis = o3d.visualization.Visualizer()
12
+ vis.create_window()
13
+ vis.add_geometry(point_cloud)
14
+
15
+ # Render the visualization and get the image
16
+ vis.poll_events()
17
+ vis.update_renderer()
18
+ img = vis.capture_screen_float_buffer()
19
+
20
+ # Convert image to PIL Image format
21
+ pil_img = Image.fromarray(np.uint8(np.asarray(img)*255))
22
+
23
+ return pil_img
24
+
25
+ def create_file_mesh_from_pcd(pcd):
26
+
27
+ temp_file = tempfile.NamedTemporaryFile(suffix=".obj", delete=False)
28
+ file_path = temp_file.name
29
+ temp_file.close()
30
+
31
+ alpha = 2
32
+ # print(f"alpha={alpha:.3f}")
33
+ mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd, alpha)
34
+ mesh.compute_vertex_normals()
35
+ o3d.io.write_triangle_mesh(file_path, mesh, write_triangle_uvs=True)
36
+ return file_path
37
+
38
+ def plane_detection(pointcloud_path, voxel_size=0.05, distance_threshold=0.01, num_iterations=1000):
39
+ # Load point cloud from file
40
+ pcd = o3d.io.read_point_cloud(pointcloud_path.name)
41
+
42
+ # Downsample the point cloud to reduce computational load
43
+ pcd = pcd.voxel_down_sample(voxel_size=voxel_size)
44
+
45
+ # Find plane using RANSAC algorithm
46
+ plane_model, inliers = pcd.segment_plane(distance_threshold=distance_threshold,
47
+ ransac_n=3,
48
+ num_iterations=num_iterations)
49
+
50
+ # Get inlier and outlier point cloud
51
+ inlier_cloud = pcd.select_by_index(inliers)
52
+ outlier_cloud = pcd.select_by_index(inliers, invert=True)
53
+ # extract the coefficients of the plane
54
+ a, b, c, d = plane_model
55
+ plane_model = np.array([[a], [b], [c], [d]])
56
+ df = pd.DataFrame(plane_model.reshape(1, 4), columns=["a", "b", "c", "d"])
57
+ input_path = create_file_mesh_from_pcd(pcd)
58
+ inlier_path = create_file_mesh_from_pcd(inlier_cloud)
59
+ outlier_path = create_file_mesh_from_pcd(outlier_cloud)
60
+ # Return inlier point cloud, outlier point cloud, and plane model
61
+ # return point_cloud_to_image(inlier_cloud), point_cloud_to_image(outlier_cloud), df
62
+ return input_path, inlier_path, outlier_path, df
63
+
64
+ outputs = [
65
+ # show pcd inlier point cloud
66
+ Model3D(label="Input Cloud", clear_color=[1.0, 1.0, 1.0, 1.0]),
67
+ # show pcd inlier point cloud
68
+ Model3D(label="Inlier Cloud", clear_color=[1.0, 1.0, 1.0, 1.0]),
69
+ # show pcd outlier point cloud
70
+ Model3D(label="Outlier Cloud", clear_color=[1.0, 1.0, 1.0, 1.0]),
71
+ # show the centroids and counts, which is a numpy array
72
+ Dataframe(label="Coefficients of the plane model", type="pandas")
73
+ ]
74
+
75
+ # Create Gradio interface
76
+ iface = gr.Interface(plane_detection,
77
+ inputs=[
78
+ File(label="Point cloud file (.ply or .pcd format)"),
79
+ Slider(label="Voxel size", minimum=1, maximum=50, step=1, value=2),
80
+ Slider(label="Distance threshold", minimum=0.5, maximum=50, step=0.5, value=5),
81
+ Slider(label="Number of iterations", minimum=1, maximum=10000, step=1, value=100)
82
+ ],
83
+ outputs=outputs,
84
+ title="Plane Detection using RANSAC",
85
+ description="This app takes as input a point cloud file (.ply or .pcd format), voxel size, distance threshold, and number of iterations, finds a plane using RANSAC algorithm, displays the inlier and outlier point clouds, and returns the inlier point cloud, outlier point cloud, and the plane model.",
86
+ allow_flagging="never"
87
+ )
88
+
89
+
90
+ # Launch the interface
91
+ iface.launch()