lemonaddie commited on
Commit
c32d0ce
1 Parent(s): 5f0d3d8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +342 -181
app.py CHANGED
@@ -11,7 +11,6 @@ from PIL import Image
11
 
12
  from gradio_imageslider import ImageSlider
13
 
14
-
15
  def process(
16
  pipe,
17
  path_input,
@@ -21,6 +20,11 @@ def process(
21
  path_out_16bit=None,
22
  path_out_fp32=None,
23
  path_out_vis=None,
 
 
 
 
 
24
  ):
25
  if path_out_vis is not None:
26
  return (
@@ -60,14 +64,84 @@ def process(
60
  [path_out_16bit, path_out_fp32, path_out_vis],
61
  )
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  def run_demo_server(pipe):
64
  process_pipe = functools.partial(process, pipe)
65
-
66
  os.environ["GRADIO_ALLOW_FLAGGING"] = "never"
67
-
68
  with gr.Blocks(
69
  analytics_enabled=False,
70
- title="Geowizard Depth and Normal Estimation",
71
  css="""
72
  #download {
73
  height: 118px;
@@ -82,7 +156,28 @@ def run_demo_server(pipe):
82
  """,
83
  ) as demo:
84
  gr.Markdown(
85
- """ttt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  """
87
  )
88
 
@@ -148,155 +243,221 @@ def run_demo_server(pipe):
148
 
149
  demo_3d_header = gr.Markdown(
150
  """
151
- <h3 align="center">Depth Maps</h3>
152
  <p align="justify">
153
- TBD
 
 
154
  result (see Pro Tips below).
155
  </p>
156
  """,
157
  render=False,
158
  )
159
 
160
- #demo_3d = gr.Row(render=False)
161
- # with demo_3d:
162
- # with gr.Column():
163
- # with gr.Accordion("3D printing demo: Main options", open=True):
164
- # plane_near = gr.Slider(
165
- # label="Relative position of the near plane (between 0 and 1)",
166
- # minimum=0.0,
167
- # maximum=1.0,
168
- # step=0.001,
169
- # value=0.0,
170
- # )
171
- # plane_far = gr.Slider(
172
- # label="Relative position of the far plane (between near and 1)",
173
- # minimum=0.0,
174
- # maximum=1.0,
175
- # step=0.001,
176
- # value=1.0,
177
- # )
178
- # embossing = gr.Slider(
179
- # label="Embossing level",
180
- # minimum=0,
181
- # maximum=100,
182
- # step=1,
183
- # value=20,
184
- # )
185
- # with gr.Accordion("3D printing demo: Advanced options", open=False):
186
- # size_longest_px = gr.Slider(
187
- # label="Size (px) of the longest side",
188
- # minimum=256,
189
- # maximum=1024,
190
- # step=256,
191
- # value=512,
192
- # )
193
- # size_longest_cm = gr.Slider(
194
- # label="Size (cm) of the longest side",
195
- # minimum=1,
196
- # maximum=100,
197
- # step=1,
198
- # value=10,
199
- # )
200
- # filter_size = gr.Slider(
201
- # label="Size (px) of the smoothing filter",
202
- # minimum=1,
203
- # maximum=5,
204
- # step=2,
205
- # value=3,
206
- # )
207
- # frame_thickness = gr.Slider(
208
- # label="Frame thickness",
209
- # minimum=0,
210
- # maximum=100,
211
- # step=1,
212
- # value=5,
213
- # )
214
- # frame_near = gr.Slider(
215
- # label="Frame's near plane offset",
216
- # minimum=-100,
217
- # maximum=100,
218
- # step=1,
219
- # value=1,
220
- # )
221
- # frame_far = gr.Slider(
222
- # label="Frame's far plane offset",
223
- # minimum=1,
224
- # maximum=10,
225
- # step=1,
226
- # value=1,
227
- # )
228
- # with gr.Row():
229
- # submit_3d = gr.Button(value="Create 3D", variant="primary")
230
- # clear_3d = gr.Button(value="Clear 3D")
231
- # gr.Markdown(
232
- # """
233
- # <h5 align="center">Pro Tips</h5>
234
- # <ol>
235
- # <li><b>Re-render with new parameters</b>: Click "Clear 3D" and then "Create 3D".</li>
236
- # <li><b>Adjust 3D scale and cut-off focus</b>: Set the frame's near plane offset to the
237
- # minimum and use 3D preview to evaluate depth scaling. Repeat until the scale is correct and
238
- # everything important is in the focus. Set the optimal value for frame's near
239
- # plane offset as a last step.</li>
240
- # <li><b>Increase details</b>: Decrease size of the smoothing filter (also increases noise).</li>
241
- # </ol>
242
- # """
243
- # )
244
-
245
- # with gr.Column():
246
- # viewer_3d = gr.Model3D(
247
- # camera_position=(75.0, 90.0, 1.25),
248
- # elem_classes="viewport",
249
- # label="3D preview (low-res, relief highlight)",
250
- # interactive=False,
251
- # )
252
- # files_3d = gr.Files(
253
- # label="3D model outputs (high-res)",
254
- # elem_id="download",
255
- # interactive=False,
256
- # )
257
 
258
  blocks_settings_depth = [ensemble_size, denoise_steps, processing_res]
259
- # # blocks_settings_3d = [plane_near, plane_far, embossing, size_longest_px, size_longest_cm, filter_size,
260
- # # frame_thickness, frame_near, frame_far]
261
- # blocks_settings = blocks_settings_depth + blocks_settings_3d
262
- blocks_settings = blocks_settings_depth
263
- # map_id_to_default = {b._id: b.value for b in blocks_settings}
264
-
265
- # inputs = [
266
- # input_image,
267
- # ensemble_size,
268
- # denoise_steps,
269
- # processing_res,
270
- # input_output_16bit,
271
- # input_output_fp32,
272
- # input_output_vis,
273
- # plane_near,
274
- # plane_far,
275
- # embossing,
276
- # filter_size,
277
- # frame_near,
278
- # ]
279
- # outputs = [
280
- # submit_btn,
281
- # input_image,
282
- # output_slider,
283
- # files,
284
- # ]
285
-
286
- # def submit_depth_fn(*args):
287
- # out = list(process_pipe(*args))
288
- # out = [gr.Button(interactive=False), gr.Image(interactive=False)] + out
289
- # return out
290
-
291
- # submit_btn.click(
292
- # fn=submit_depth_fn,
293
- # inputs=inputs,
294
- # outputs=outputs,
295
- # concurrency_limit=1,
296
- # )
297
-
298
- # demo_3d_header.render()
299
- # demo_3d.render()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
 
301
  def clear_fn():
302
  out = []
@@ -304,7 +465,7 @@ def run_demo_server(pipe):
304
  out.append(map_id_to_default[b._id])
305
  out += [
306
  gr.Button(interactive=True),
307
- #gr.Button(interactive=True),
308
  gr.Image(value=None, interactive=True),
309
  None, None, None, None, None, None, None,
310
  ]
@@ -315,50 +476,50 @@ def run_demo_server(pipe):
315
  inputs=[],
316
  outputs=blocks_settings + [
317
  submit_btn,
318
- #submit_3d,
319
  input_image,
320
  input_output_16bit,
321
  input_output_fp32,
322
  input_output_vis,
323
  output_slider,
324
  files,
325
- #viewer_3d,
326
- #files_3d,
327
  ],
328
  )
329
 
330
- # def submit_3d_fn(*args):
331
- # out = list(process_3d(*args))
332
- # out = [gr.Button(interactive=False)] + out
333
- # return out
334
-
335
- # submit_3d.click(
336
- # fn=submit_3d_fn,
337
- # inputs=[
338
- # input_image,
339
- # files,
340
- # size_longest_px,
341
- # size_longest_cm,
342
- # filter_size,
343
- # plane_near,
344
- # plane_far,
345
- # embossing,
346
- # frame_thickness,
347
- # frame_near,
348
- # frame_far,
349
- # ],
350
- # outputs=[submit_3d, viewer_3d, files_3d],
351
- # concurrency_limit=1,
352
- # )
353
-
354
- # def clear_3d_fn():
355
- # return [gr.Button(interactive=True), None, None]
356
-
357
- # clear_3d.click(
358
- # fn=clear_3d_fn,
359
- # inputs=[],
360
- # outputs=[submit_3d, viewer_3d, files_3d],
361
- # )
362
 
363
  demo.queue(
364
  api_open=False,
 
11
 
12
  from gradio_imageslider import ImageSlider
13
 
 
14
  def process(
15
  pipe,
16
  path_input,
 
20
  path_out_16bit=None,
21
  path_out_fp32=None,
22
  path_out_vis=None,
23
+ _input_3d_plane_near=None,
24
+ _input_3d_plane_far=None,
25
+ _input_3d_embossing=None,
26
+ _input_3d_filter_size=None,
27
+ _input_3d_frame_near=None,
28
  ):
29
  if path_out_vis is not None:
30
  return (
 
64
  [path_out_16bit, path_out_fp32, path_out_vis],
65
  )
66
 
67
+
68
+ def process_3d(
69
+ input_image,
70
+ files,
71
+ size_longest_px,
72
+ size_longest_cm,
73
+ filter_size,
74
+ plane_near,
75
+ plane_far,
76
+ embossing,
77
+ frame_thickness,
78
+ frame_near,
79
+ frame_far,
80
+ ):
81
+ if input_image is None or len(files) < 1:
82
+ raise gr.Error("Please upload an image (or use examples) and compute depth first")
83
+
84
+ if plane_near >= plane_far:
85
+ raise gr.Error("NEAR plane must have a value smaller than the FAR plane")
86
+
87
+ def _process_3d(size_longest_px, filter_size, vertex_colors, scene_lights, output_model_scale=None):
88
+ image_rgb = input_image
89
+ image_depth = files[0]
90
+
91
+ image_rgb_basename, image_rgb_ext = os.path.splitext(image_rgb)
92
+ image_depth_basename, image_depth_ext = os.path.splitext(image_depth)
93
+
94
+ image_rgb_content = Image.open(image_rgb)
95
+ image_rgb_w, image_rgb_h = image_rgb_content.width, image_rgb_content.height
96
+ image_rgb_d = max(image_rgb_w, image_rgb_h)
97
+ image_new_w = size_longest_px * image_rgb_w // image_rgb_d
98
+ image_new_h = size_longest_px * image_rgb_h // image_rgb_d
99
+
100
+ image_rgb_new = image_rgb_basename + f"_{size_longest_px}" + image_rgb_ext
101
+ image_depth_new = image_depth_basename + f"_{size_longest_px}" + image_depth_ext
102
+ image_rgb_content.resize((image_new_w, image_new_h), Image.LANCZOS).save(
103
+ image_rgb_new
104
+ )
105
+ Image.open(image_depth).resize((image_new_w, image_new_h), Image.LANCZOS).save(
106
+ image_depth_new
107
+ )
108
+
109
+ path_glb, path_stl = extrude_depth_3d(
110
+ image_rgb_new,
111
+ image_depth_new,
112
+ output_model_scale=size_longest_cm * 10 if output_model_scale is None else output_model_scale,
113
+ filter_size=filter_size,
114
+ coef_near=plane_near,
115
+ coef_far=plane_far,
116
+ emboss=embossing / 100,
117
+ f_thic=frame_thickness / 100,
118
+ f_near=frame_near / 100,
119
+ f_back=frame_far / 100,
120
+ vertex_colors=vertex_colors,
121
+ scene_lights=scene_lights,
122
+ )
123
+
124
+ return path_glb, path_stl
125
+
126
+ path_viewer_glb, _ = _process_3d(256, filter_size, vertex_colors=False, scene_lights=True, output_model_scale=1)
127
+ path_files_glb, path_files_stl = _process_3d(size_longest_px, filter_size, vertex_colors=True, scene_lights=False)
128
+
129
+ # sanitize 3d viewer glb path to keep babylon.js happy
130
+ path_viewer_glb_sanitized = os.path.join(os.path.dirname(path_viewer_glb), "preview.glb")
131
+ if path_viewer_glb_sanitized != path_viewer_glb:
132
+ os.rename(path_viewer_glb, path_viewer_glb_sanitized)
133
+ path_viewer_glb = path_viewer_glb_sanitized
134
+
135
+ return path_viewer_glb, [path_files_glb, path_files_stl]
136
+
137
+
138
  def run_demo_server(pipe):
139
  process_pipe = functools.partial(process, pipe)
 
140
  os.environ["GRADIO_ALLOW_FLAGGING"] = "never"
141
+
142
  with gr.Blocks(
143
  analytics_enabled=False,
144
+ title="Marigold Depth Estimation",
145
  css="""
146
  #download {
147
  height: 118px;
 
156
  """,
157
  ) as demo:
158
  gr.Markdown(
159
+ """
160
+ <h1 align="center">Marigold Depth Estimation</h1>
161
+ <p align="center">
162
+ <a title="Website" href="https://marigoldmonodepth.github.io/" target="_blank" rel="noopener noreferrer" style="display: inline-block;">
163
+ <img src="https://www.obukhov.ai/img/badges/badge-website.svg">
164
+ </a>
165
+ <a title="arXiv" href="https://arxiv.org/abs/2312.02145" target="_blank" rel="noopener noreferrer" style="display: inline-block;">
166
+ <img src="https://www.obukhov.ai/img/badges/badge-pdf.svg">
167
+ </a>
168
+ <a title="Github" href="https://github.com/prs-eth/marigold" target="_blank" rel="noopener noreferrer" style="display: inline-block;">
169
+ <img src="https://img.shields.io/github/stars/prs-eth/marigold?label=GitHub%20%E2%98%85&logo=github&color=C8C" alt="badge-github-stars">
170
+ </a>
171
+ <a title="Social" href="https://twitter.com/antonobukhov1" target="_blank" rel="noopener noreferrer" style="display: inline-block;">
172
+ <img src="https://www.obukhov.ai/img/badges/badge-social.svg" alt="social">
173
+ </a>
174
+ </p>
175
+ <p align="justify">
176
+ Marigold is the new state-of-the-art depth estimator for images in the wild.
177
+ Upload your image into the <b>left</b> side, or click any of the <b>examples</b> below.
178
+ The result will be computed and appear on the <b>right</b> in the output comparison window.
179
+ <b style="color: red;">NEW</b>: Scroll down to the new 3D printing part of the demo!
180
+ </p>
181
  """
182
  )
183
 
 
243
 
244
  demo_3d_header = gr.Markdown(
245
  """
246
+ <h3 align="center">3D Printing Depth Maps</h3>
247
  <p align="justify">
248
+ This part of the demo uses Marigold depth maps estimated in the previous step to create a
249
+ 3D-printable model. The models are watertight, with correct normals, and exported in the STL format.
250
+ We recommended creating the first model with the default parameters and iterating on it until the best
251
  result (see Pro Tips below).
252
  </p>
253
  """,
254
  render=False,
255
  )
256
 
257
+ demo_3d = gr.Row(render=False)
258
+ with demo_3d:
259
+ with gr.Column():
260
+ with gr.Accordion("3D printing demo: Main options", open=True):
261
+ plane_near = gr.Slider(
262
+ label="Relative position of the near plane (between 0 and 1)",
263
+ minimum=0.0,
264
+ maximum=1.0,
265
+ step=0.001,
266
+ value=0.0,
267
+ )
268
+ plane_far = gr.Slider(
269
+ label="Relative position of the far plane (between near and 1)",
270
+ minimum=0.0,
271
+ maximum=1.0,
272
+ step=0.001,
273
+ value=1.0,
274
+ )
275
+ embossing = gr.Slider(
276
+ label="Embossing level",
277
+ minimum=0,
278
+ maximum=100,
279
+ step=1,
280
+ value=20,
281
+ )
282
+ with gr.Accordion("3D printing demo: Advanced options", open=False):
283
+ size_longest_px = gr.Slider(
284
+ label="Size (px) of the longest side",
285
+ minimum=256,
286
+ maximum=1024,
287
+ step=256,
288
+ value=512,
289
+ )
290
+ size_longest_cm = gr.Slider(
291
+ label="Size (cm) of the longest side",
292
+ minimum=1,
293
+ maximum=100,
294
+ step=1,
295
+ value=10,
296
+ )
297
+ filter_size = gr.Slider(
298
+ label="Size (px) of the smoothing filter",
299
+ minimum=1,
300
+ maximum=5,
301
+ step=2,
302
+ value=3,
303
+ )
304
+ frame_thickness = gr.Slider(
305
+ label="Frame thickness",
306
+ minimum=0,
307
+ maximum=100,
308
+ step=1,
309
+ value=5,
310
+ )
311
+ frame_near = gr.Slider(
312
+ label="Frame's near plane offset",
313
+ minimum=-100,
314
+ maximum=100,
315
+ step=1,
316
+ value=1,
317
+ )
318
+ frame_far = gr.Slider(
319
+ label="Frame's far plane offset",
320
+ minimum=1,
321
+ maximum=10,
322
+ step=1,
323
+ value=1,
324
+ )
325
+ with gr.Row():
326
+ submit_3d = gr.Button(value="Create 3D", variant="primary")
327
+ clear_3d = gr.Button(value="Clear 3D")
328
+ gr.Markdown(
329
+ """
330
+ <h5 align="center">Pro Tips</h5>
331
+ <ol>
332
+ <li><b>Re-render with new parameters</b>: Click "Clear 3D" and then "Create 3D".</li>
333
+ <li><b>Adjust 3D scale and cut-off focus</b>: Set the frame's near plane offset to the
334
+ minimum and use 3D preview to evaluate depth scaling. Repeat until the scale is correct and
335
+ everything important is in the focus. Set the optimal value for frame's near
336
+ plane offset as a last step.</li>
337
+ <li><b>Increase details</b>: Decrease size of the smoothing filter (also increases noise).</li>
338
+ </ol>
339
+ """
340
+ )
341
+
342
+ with gr.Column():
343
+ viewer_3d = gr.Model3D(
344
+ camera_position=(75.0, 90.0, 1.25),
345
+ elem_classes="viewport",
346
+ label="3D preview (low-res, relief highlight)",
347
+ interactive=False,
348
+ )
349
+ files_3d = gr.Files(
350
+ label="3D model outputs (high-res)",
351
+ elem_id="download",
352
+ interactive=False,
353
+ )
354
 
355
  blocks_settings_depth = [ensemble_size, denoise_steps, processing_res]
356
+ blocks_settings_3d = [plane_near, plane_far, embossing, size_longest_px, size_longest_cm, filter_size,
357
+ frame_thickness, frame_near, frame_far]
358
+ blocks_settings = blocks_settings_depth + blocks_settings_3d
359
+ map_id_to_default = {b._id: b.value for b in blocks_settings}
360
+
361
+ inputs = [
362
+ input_image,
363
+ ensemble_size,
364
+ denoise_steps,
365
+ processing_res,
366
+ input_output_16bit,
367
+ input_output_fp32,
368
+ input_output_vis,
369
+ plane_near,
370
+ plane_far,
371
+ embossing,
372
+ filter_size,
373
+ frame_near,
374
+ ]
375
+ outputs = [
376
+ submit_btn,
377
+ input_image,
378
+ output_slider,
379
+ files,
380
+ ]
381
+
382
+ def submit_depth_fn(*args):
383
+ out = list(process_pipe(*args))
384
+ out = [gr.Button(interactive=False), gr.Image(interactive=False)] + out
385
+ return out
386
+
387
+ submit_btn.click(
388
+ fn=submit_depth_fn,
389
+ inputs=inputs,
390
+ outputs=outputs,
391
+ concurrency_limit=1,
392
+ )
393
+
394
+ gr.Examples(
395
+ fn=submit_depth_fn,
396
+ examples=[
397
+ [
398
+ "files/bee.jpg",
399
+ 10, # ensemble_size
400
+ 10, # denoise_steps
401
+ 768, # processing_res
402
+ "files/bee_depth_16bit.png",
403
+ "files/bee_depth_fp32.npy",
404
+ "files/bee_depth_colored.png",
405
+ 0.0, # plane_near
406
+ 0.5, # plane_far
407
+ 20, # embossing
408
+ 3, # filter_size
409
+ 0, # frame_near
410
+ ],
411
+ [
412
+ "files/cat.jpg",
413
+ 10, # ensemble_size
414
+ 10, # denoise_steps
415
+ 768, # processing_res
416
+ "files/cat_depth_16bit.png",
417
+ "files/cat_depth_fp32.npy",
418
+ "files/cat_depth_colored.png",
419
+ 0.0, # plane_near
420
+ 0.3, # plane_far
421
+ 20, # embossing
422
+ 3, # filter_size
423
+ 0, # frame_near
424
+ ],
425
+ [
426
+ "files/swings.jpg",
427
+ 10, # ensemble_size
428
+ 10, # denoise_steps
429
+ 768, # processing_res
430
+ "files/swings_depth_16bit.png",
431
+ "files/swings_depth_fp32.npy",
432
+ "files/swings_depth_colored.png",
433
+ 0.05, # plane_near
434
+ 0.25, # plane_far
435
+ 10, # embossing
436
+ 1, # filter_size
437
+ 0, # frame_near
438
+ ],
439
+ [
440
+ "files/einstein.jpg",
441
+ 10, # ensemble_size
442
+ 10, # denoise_steps
443
+ 768, # processing_res
444
+ "files/einstein_depth_16bit.png",
445
+ "files/einstein_depth_fp32.npy",
446
+ "files/einstein_depth_colored.png",
447
+ 0.0, # plane_near
448
+ 0.5, # plane_far
449
+ 50, # embossing
450
+ 3, # filter_size
451
+ -15, # frame_near
452
+ ],
453
+ ],
454
+ inputs=inputs,
455
+ outputs=outputs,
456
+ cache_examples=True,
457
+ )
458
+
459
+ demo_3d_header.render()
460
+ demo_3d.render()
461
 
462
  def clear_fn():
463
  out = []
 
465
  out.append(map_id_to_default[b._id])
466
  out += [
467
  gr.Button(interactive=True),
468
+ gr.Button(interactive=True),
469
  gr.Image(value=None, interactive=True),
470
  None, None, None, None, None, None, None,
471
  ]
 
476
  inputs=[],
477
  outputs=blocks_settings + [
478
  submit_btn,
479
+ submit_3d,
480
  input_image,
481
  input_output_16bit,
482
  input_output_fp32,
483
  input_output_vis,
484
  output_slider,
485
  files,
486
+ viewer_3d,
487
+ files_3d,
488
  ],
489
  )
490
 
491
+ def submit_3d_fn(*args):
492
+ out = list(process_3d(*args))
493
+ out = [gr.Button(interactive=False)] + out
494
+ return out
495
+
496
+ submit_3d.click(
497
+ fn=submit_3d_fn,
498
+ inputs=[
499
+ input_image,
500
+ files,
501
+ size_longest_px,
502
+ size_longest_cm,
503
+ filter_size,
504
+ plane_near,
505
+ plane_far,
506
+ embossing,
507
+ frame_thickness,
508
+ frame_near,
509
+ frame_far,
510
+ ],
511
+ outputs=[submit_3d, viewer_3d, files_3d],
512
+ concurrency_limit=1,
513
+ )
514
+
515
+ def clear_3d_fn():
516
+ return [gr.Button(interactive=True), None, None]
517
+
518
+ clear_3d.click(
519
+ fn=clear_3d_fn,
520
+ inputs=[],
521
+ outputs=[submit_3d, viewer_3d, files_3d],
522
+ )
523
 
524
  demo.queue(
525
  api_open=False,