mattiagatti commited on
Commit
09dfd9b
·
0 Parent(s):

Initial commit

Browse files
Files changed (5) hide show
  1. .gitattributes +33 -0
  2. README.md +18 -0
  3. app.py +125 -0
  4. examples/bed.png +0 -0
  5. requirements.txt +7 -0
.gitattributes ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ftz filter=lfs diff=lfs merge=lfs -text
6
+ *.gz filter=lfs diff=lfs merge=lfs -text
7
+ *.h5 filter=lfs diff=lfs merge=lfs -text
8
+ *.joblib filter=lfs diff=lfs merge=lfs -text
9
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
10
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
11
+ *.model filter=lfs diff=lfs merge=lfs -text
12
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
13
+ *.npy filter=lfs diff=lfs merge=lfs -text
14
+ *.npz filter=lfs diff=lfs merge=lfs -text
15
+ *.onnx filter=lfs diff=lfs merge=lfs -text
16
+ *.ot filter=lfs diff=lfs merge=lfs -text
17
+ *.parquet filter=lfs diff=lfs merge=lfs -text
18
+ *.pb filter=lfs diff=lfs merge=lfs -text
19
+ *.pickle filter=lfs diff=lfs merge=lfs -text
20
+ *.pkl filter=lfs diff=lfs merge=lfs -text
21
+ *.pt filter=lfs diff=lfs merge=lfs -text
22
+ *.pth filter=lfs diff=lfs merge=lfs -text
23
+ *.rar filter=lfs diff=lfs merge=lfs -text
24
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
25
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
26
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
27
+ *.tflite filter=lfs diff=lfs merge=lfs -text
28
+ *.tgz filter=lfs diff=lfs merge=lfs -text
29
+ *.wasm filter=lfs diff=lfs merge=lfs -text
30
+ *.xz filter=lfs diff=lfs merge=lfs -text
31
+ *.zip filter=lfs diff=lfs merge=lfs -text
32
+ *.zst filter=lfs diff=lfs merge=lfs -text
33
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Image2mesh
3
+ emoji: 👁
4
+ colorFrom: green
5
+ colorTo: blue
6
+ python_version: 3.11
7
+ sdk: gradio
8
+ sdk_version: 4.36.1
9
+ app_file: app.py
10
+ pinned: false
11
+ ---
12
+
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
14
+
15
+ ```
16
+ pip install -r requirements.txt
17
+ python3.11 app.py
18
+ ```
app.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import matplotlib.pyplot as plt
3
+ import numpy as np
4
+ import open3d as o3d
5
+ import os
6
+ from PIL import Image
7
+ import tempfile
8
+ import torch
9
+ from transformers import GLPNImageProcessor, GLPNForDepthEstimation
10
+
11
+
12
+ def predict_depth(image):
13
+ # load and resize the input image
14
+ new_height = 480 if image.height > 480 else image.height
15
+ new_height -= (new_height % 32)
16
+ new_width = int(new_height * image.width / image.height)
17
+ diff = new_width % 32
18
+ new_width = new_width - diff if diff < 16 else new_width + 32 - diff
19
+ new_size = (new_width, new_height)
20
+ image = image.resize(new_size)
21
+
22
+ # prepare image for the model
23
+ inputs = feature_extractor(images=image, return_tensors="pt")
24
+
25
+ # get the prediction from the model
26
+ with torch.no_grad():
27
+ outputs = model(**inputs)
28
+ predicted_depth = outputs.predicted_depth
29
+
30
+ output = predicted_depth.squeeze().cpu().numpy() * 1000.0
31
+
32
+ # remove borders
33
+ pad = 16
34
+ output = output[pad:-pad, pad:-pad]
35
+ image = image.crop((pad, pad, image.width - pad, image.height - pad))
36
+
37
+ return image, output
38
+
39
+
40
+ def generate_mesh(image, depth_image, quality):
41
+ width, height = image.size
42
+
43
+ # depth_image = (depth_map * 255 / np.max(depth_map)).astype('uint8')
44
+ image = np.array(image)
45
+
46
+ # create rgbd image
47
+ depth_o3d = o3d.geometry.Image(depth_image)
48
+ image_o3d = o3d.geometry.Image(image)
49
+ rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(image_o3d, depth_o3d,
50
+ convert_rgb_to_intensity=False)
51
+
52
+ # camera settings
53
+ camera_intrinsic = o3d.camera.PinholeCameraIntrinsic()
54
+ camera_intrinsic.set_intrinsics(width, height, 500, 500, width / 2, height / 2)
55
+
56
+ # create point cloud
57
+ pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, camera_intrinsic)
58
+
59
+ # outliers removal
60
+ cl, ind = pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=20.0)
61
+ pcd = pcd.select_by_index(ind)
62
+
63
+ # estimate normals
64
+ pcd.estimate_normals()
65
+ pcd.orient_normals_to_align_with_direction(orientation_reference=(0., 0., -1.))
66
+
67
+ # surface reconstruction
68
+ mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=quality, n_threads=1)[0]
69
+
70
+ # rotate the mesh
71
+ rotation = mesh.get_rotation_matrix_from_xyz((np.pi, np.pi, 0))
72
+ mesh.rotate(rotation, center=(0, 0, 0))
73
+ mesh.scale(256, center=(0, 0, 0))
74
+
75
+ # save the mesh
76
+ temp_name = next(tempfile._get_candidate_names()) + '.obj'
77
+ o3d.io.write_triangle_mesh(temp_name, mesh)
78
+
79
+ return temp_name
80
+
81
+
82
+ def predict(image, quality):
83
+ image, depth_map = predict_depth(image)
84
+ depth_image = (depth_map * 255 / np.max(depth_map)).astype('uint8')
85
+ mesh_path = generate_mesh(image, depth_image, quality + 5)
86
+ colormap = plt.get_cmap('plasma')
87
+ depth_image = (colormap(depth_image) * 255).astype('uint8')
88
+ depth_image = Image.fromarray(depth_image)
89
+
90
+ return depth_image, mesh_path
91
+
92
+
93
+ feature_extractor = GLPNImageProcessor.from_pretrained("vinvino02/glpn-nyu")
94
+ model = GLPNForDepthEstimation.from_pretrained("vinvino02/glpn-nyu")
95
+
96
+
97
+ # GUI
98
+ title = 'Image2Mesh'
99
+ description = 'Demo based on my <a href="https://towardsdatascience.com/generate-a-3d-mesh-from-an-image-with-python' \
100
+ '-12210c73e5cc">article</a>. This demo predicts the depth of an image and then generates the 3D mesh. ' \
101
+ 'Choosing a higher quality increases the time to generate the mesh. You can download the mesh by ' \
102
+ 'clicking the top-right button on the 3D viewer. '
103
+ examples = [[f'examples/{name}', 3] for name in sorted(os.listdir('examples'))]
104
+
105
+ # example image source:
106
+ # N. Silberman, D. Hoiem, P. Kohli, and Rob Fergus,
107
+ # Indoor Segmentation and Support Inference from RGBD Images (2012)
108
+
109
+ iface = gr.Interface(
110
+ fn=predict,
111
+ inputs=[
112
+ gr.Image(type='pil', label='Input Image'),
113
+ gr.Slider(1, 5, step=1, value=3, label='Mesh quality')
114
+ ],
115
+ outputs=[
116
+ gr.Image(label='Depth'),
117
+ gr.Model3D(label='3D Model', clear_color=[0.0, 0.0, 0.0, 0.0])
118
+ ],
119
+ examples=examples,
120
+ allow_flagging='never',
121
+ cache_examples=False,
122
+ title=title,
123
+ description=description
124
+ )
125
+ iface.launch()
examples/bed.png ADDED
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio==4.36.1
2
+ matplotlib==3.9.0
3
+ numpy==1.26.4
4
+ open3d==0.18.0
5
+ Pillow==10.3.0
6
+ torch==2.3.0
7
+ transformers==4.41.0