Spaces:
Paused
Paused
Chao Xu
commited on
Commit
โข
2337f0d
1
Parent(s):
d492a58
adjust layout and fix rerun bug
Browse files
app.py
CHANGED
@@ -55,16 +55,16 @@ _DESCRIPTION = '''
|
|
55 |
We reconstruct a 3D textured mesh from a single image by initially predicting multi-view images and then lifting them to 3D.
|
56 |
'''
|
57 |
|
58 |
-
_USER_GUIDE = "Please upload an image in the
|
59 |
_BBOX_1 = "Predicting bounding box for the input image..."
|
60 |
_BBOX_2 = "Bounding box adjusted. Continue adjusting or **Run Generation**."
|
61 |
_BBOX_3 = "Bounding box predicted. Adjust it using sliders or **Run Generation**."
|
62 |
_SAM = "Preprocessing the input image... (safety check, SAM segmentation, *etc*.)"
|
63 |
-
_GEN_1 = "Predicting multi-view images... (may take \~
|
64 |
-
_GEN_2 = "Predicting nearby views and generating mesh... (may take \~
|
65 |
-
_DONE = "Done! Mesh is shown
|
66 |
_REGEN_1 = "Selected view(s) are regenerated. You can click **Regenerate nearby views and mesh**. <br> Alternatively, if the regenerated view(s) are still not satisfactory, you can repeat the previous step (select the view and regenerate)."
|
67 |
-
_REGEN_2 = "Regeneration done.
|
68 |
|
69 |
class CameraVisualizer:
|
70 |
def __init__(self, gradio_plot):
|
@@ -197,7 +197,7 @@ class CameraVisualizer:
|
|
197 |
# width=640,
|
198 |
# height=480,
|
199 |
# height=400,
|
200 |
-
height=
|
201 |
autosize=True,
|
202 |
hovermode=False,
|
203 |
margin=go.layout.Margin(l=0, r=0, b=0, t=0),
|
@@ -279,7 +279,7 @@ def stage1_run(models, device, cam_vis, tmp_dir,
|
|
279 |
rerun_idx = [i for i in range(len(btn_retrys)) if btn_retrys[i]]
|
280 |
# elev_output = estimate_elev(tmp_dir)
|
281 |
# if elev_output > 75:
|
282 |
-
if 90-elev > 75:
|
283 |
rerun_idx_in = [i if i < 4 else i+4 for i in rerun_idx]
|
284 |
else:
|
285 |
rerun_idx_in = rerun_idx
|
@@ -525,89 +525,53 @@ def run_demo(
|
|
525 |
|
526 |
|
527 |
# Compose demo layout & data flow.
|
528 |
-
css="#model-3d-out {height: 400px;}"
|
529 |
with gr.Blocks(title=_TITLE, css=css) as demo:
|
530 |
gr.Markdown('# ' + _TITLE)
|
531 |
gr.Markdown(_DESCRIPTION)
|
532 |
|
533 |
with gr.Row(variant='panel'):
|
534 |
-
with gr.Column(scale=
|
535 |
-
image_block = gr.Image(type='pil', image_mode='RGBA', label='Input image', tool=None)
|
536 |
-
with gr.Row():
|
537 |
-
bbox_block = gr.Image(type='pil', label="Bounding box", interactive=False).style(height=300)
|
538 |
-
sam_block = gr.Image(type='pil', label="SAM output", interactive=False)
|
539 |
-
max_width = max_height = 256
|
540 |
-
with gr.Row():
|
541 |
-
x_min_slider = gr.Slider(
|
542 |
-
label="X min",
|
543 |
-
interactive=True,
|
544 |
-
value=0,
|
545 |
-
minimum=0,
|
546 |
-
maximum=max_width,
|
547 |
-
step=1,
|
548 |
-
)
|
549 |
-
y_min_slider = gr.Slider(
|
550 |
-
label="Y min",
|
551 |
-
interactive=True,
|
552 |
-
value=0,
|
553 |
-
minimum=0,
|
554 |
-
maximum=max_height,
|
555 |
-
step=1,
|
556 |
-
)
|
557 |
-
with gr.Row():
|
558 |
-
x_max_slider = gr.Slider(
|
559 |
-
label="X max",
|
560 |
-
interactive=True,
|
561 |
-
value=max_width,
|
562 |
-
minimum=0,
|
563 |
-
maximum=max_width,
|
564 |
-
step=1,
|
565 |
-
)
|
566 |
-
y_max_slider = gr.Slider(
|
567 |
-
label="Y max",
|
568 |
-
interactive=True,
|
569 |
-
value=max_height,
|
570 |
-
minimum=0,
|
571 |
-
maximum=max_height,
|
572 |
-
step=1,
|
573 |
-
)
|
574 |
-
bbox_sliders = [x_min_slider, y_min_slider, x_max_slider, y_max_slider]
|
575 |
|
576 |
-
|
577 |
-
with gr.Column(scale=1.15):
|
578 |
gr.Examples(
|
579 |
examples=examples_full, # NOTE: elements must match inputs list!
|
580 |
-
# fn=save_img,
|
581 |
-
fn=lambda x: x,
|
582 |
inputs=[image_block],
|
583 |
-
# outputs=[image_block, bbox_block, *bbox_sliders],
|
584 |
outputs=[image_block],
|
585 |
cache_examples=False,
|
586 |
-
run_on_click=True,
|
587 |
label='Examples (click one of the images below to start)',
|
588 |
)
|
589 |
-
|
590 |
-
True, label='Reduce image contrast (mitigate shadows on the backside)')
|
591 |
-
|
592 |
with gr.Accordion('Advanced options', open=False):
|
|
|
|
|
593 |
scale_slider = gr.Slider(0, 30, value=3, step=1,
|
594 |
label='Diffusion guidance scale')
|
595 |
steps_slider = gr.Slider(5, 200, value=75, step=5,
|
596 |
label='Number of diffusion inference steps')
|
597 |
|
598 |
-
# with gr.Row():
|
599 |
run_btn = gr.Button('Run Generation', variant='primary', interactive=False)
|
600 |
-
# guide_title = gr.Markdown(_GUIDE_TITLE, visible=True)
|
601 |
guide_text = gr.Markdown(_USER_GUIDE, visible=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
602 |
|
603 |
mesh_output = gr.Model3D(clear_color=[0.0, 0.0, 0.0, 0.0], label="One-2-3-45's Textured Mesh", elem_id="model-3d-out")
|
604 |
|
605 |
with gr.Row(variant='panel'):
|
606 |
with gr.Column(scale=0.85):
|
607 |
-
|
608 |
-
|
609 |
-
vis_output = gr.Plot(
|
610 |
-
label='Camera poses of the input view (red) and predicted views (blue)')
|
611 |
|
612 |
with gr.Column(scale=1.15):
|
613 |
gr.Markdown('Predicted multi-view images')
|
@@ -631,7 +595,6 @@ def run_demo(
|
|
631 |
btn_retry_6 = gr.Checkbox(label='Retry view 6')
|
632 |
btn_retry_7 = gr.Checkbox(label='Retry view 7')
|
633 |
btn_retry_8 = gr.Checkbox(label='Retry view 8')
|
634 |
-
# regen_btn = gr.Button('Regenerate selected views and mesh', variant='secondary', visible=False)
|
635 |
with gr.Row():
|
636 |
regen_view_btn = gr.Button('1. Regenerate selected view(s)', variant='secondary', visible=False)
|
637 |
regen_mesh_btn = gr.Button('2. Regenerate nearby views and mesh', variant='secondary', visible=False)
|
@@ -683,12 +646,10 @@ def run_demo(
|
|
683 |
def on_retry_button_click(*btn_retrys):
|
684 |
any_checked = any([btn_retry for btn_retry in btn_retrys])
|
685 |
print('any_checked:', any_checked, [btn_retry for btn_retry in btn_retrys])
|
686 |
-
# return regen_btn.update(visible=any_checked)
|
687 |
if any_checked:
|
688 |
return (gr.update(visible=True), gr.update(visible=True))
|
689 |
else:
|
690 |
return (gr.update(), gr.update())
|
691 |
-
# return regen_view_btn.update(visible=any_checked), regen_mesh_btn.update(visible=any_checked)
|
692 |
# make regen_btn visible when any of the btn_retry is checked
|
693 |
for btn_retry in btn_retrys:
|
694 |
# Add the event handlers to the btn_retry buttons
|
|
|
55 |
We reconstruct a 3D textured mesh from a single image by initially predicting multi-view images and then lifting them to 3D.
|
56 |
'''
|
57 |
|
58 |
+
_USER_GUIDE = "Please upload an image in the block above (or choose an example above) and click **Run Generation**."
|
59 |
_BBOX_1 = "Predicting bounding box for the input image..."
|
60 |
_BBOX_2 = "Bounding box adjusted. Continue adjusting or **Run Generation**."
|
61 |
_BBOX_3 = "Bounding box predicted. Adjust it using sliders or **Run Generation**."
|
62 |
_SAM = "Preprocessing the input image... (safety check, SAM segmentation, *etc*.)"
|
63 |
+
_GEN_1 = "Predicting multi-view images... (may take \~21 seconds) <br> Images will be shown in the bottom right blocks."
|
64 |
+
_GEN_2 = "Predicting nearby views and generating mesh... (may take \~43 seconds) <br> Mesh will be shown on the right."
|
65 |
+
_DONE = "Done! Mesh is shown on the right. <br> If it is not satisfactory, please select **Retry view** checkboxes for inaccurate views and click **Regenerate selected view(s)** at the bottom."
|
66 |
_REGEN_1 = "Selected view(s) are regenerated. You can click **Regenerate nearby views and mesh**. <br> Alternatively, if the regenerated view(s) are still not satisfactory, you can repeat the previous step (select the view and regenerate)."
|
67 |
+
_REGEN_2 = "Regeneration done. Mesh is shown on the right."
|
68 |
|
69 |
class CameraVisualizer:
|
70 |
def __init__(self, gradio_plot):
|
|
|
197 |
# width=640,
|
198 |
# height=480,
|
199 |
# height=400,
|
200 |
+
height=450,
|
201 |
autosize=True,
|
202 |
hovermode=False,
|
203 |
margin=go.layout.Margin(l=0, r=0, b=0, t=0),
|
|
|
279 |
rerun_idx = [i for i in range(len(btn_retrys)) if btn_retrys[i]]
|
280 |
# elev_output = estimate_elev(tmp_dir)
|
281 |
# if elev_output > 75:
|
282 |
+
if 90-int(elev["label"]) > 75:
|
283 |
rerun_idx_in = [i if i < 4 else i+4 for i in rerun_idx]
|
284 |
else:
|
285 |
rerun_idx_in = rerun_idx
|
|
|
525 |
|
526 |
|
527 |
# Compose demo layout & data flow.
|
528 |
+
css = "#model-3d-out {height: 400px;} #plot-out {height: 425px;}"
|
529 |
with gr.Blocks(title=_TITLE, css=css) as demo:
|
530 |
gr.Markdown('# ' + _TITLE)
|
531 |
gr.Markdown(_DESCRIPTION)
|
532 |
|
533 |
with gr.Row(variant='panel'):
|
534 |
+
with gr.Column(scale=1.2):
|
535 |
+
image_block = gr.Image(type='pil', image_mode='RGBA', label='Input image', tool=None).style(height=290)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
536 |
|
|
|
|
|
537 |
gr.Examples(
|
538 |
examples=examples_full, # NOTE: elements must match inputs list!
|
|
|
|
|
539 |
inputs=[image_block],
|
|
|
540 |
outputs=[image_block],
|
541 |
cache_examples=False,
|
|
|
542 |
label='Examples (click one of the images below to start)',
|
543 |
)
|
544 |
+
|
|
|
|
|
545 |
with gr.Accordion('Advanced options', open=False):
|
546 |
+
preprocess_chk = gr.Checkbox(
|
547 |
+
False, label='Reduce image contrast (mitigate shadows on the backside)')
|
548 |
scale_slider = gr.Slider(0, 30, value=3, step=1,
|
549 |
label='Diffusion guidance scale')
|
550 |
steps_slider = gr.Slider(5, 200, value=75, step=5,
|
551 |
label='Number of diffusion inference steps')
|
552 |
|
|
|
553 |
run_btn = gr.Button('Run Generation', variant='primary', interactive=False)
|
|
|
554 |
guide_text = gr.Markdown(_USER_GUIDE, visible=True)
|
555 |
+
|
556 |
+
with gr.Column(scale=.8):
|
557 |
+
with gr.Row():
|
558 |
+
bbox_block = gr.Image(type='pil', label="Bounding box", interactive=False).style(height=290)
|
559 |
+
sam_block = gr.Image(type='pil', label="SAM output", interactive=False)
|
560 |
+
max_width = max_height = 256
|
561 |
+
with gr.Row():
|
562 |
+
x_min_slider = gr.Slider(label="X min", interactive=True, value=0, minimum=0, maximum=max_width, step=1)
|
563 |
+
y_min_slider = gr.Slider(label="Y min", interactive=True, value=0, minimum=0, maximum=max_height, step=1)
|
564 |
+
with gr.Row():
|
565 |
+
x_max_slider = gr.Slider(label="X max", interactive=True, value=max_width, minimum=0, maximum=max_width, step=1)
|
566 |
+
y_max_slider = gr.Slider(label="Y max", interactive=True, value=max_height, minimum=0, maximum=max_height, step=1)
|
567 |
+
bbox_sliders = [x_min_slider, y_min_slider, x_max_slider, y_max_slider]
|
568 |
|
569 |
mesh_output = gr.Model3D(clear_color=[0.0, 0.0, 0.0, 0.0], label="One-2-3-45's Textured Mesh", elem_id="model-3d-out")
|
570 |
|
571 |
with gr.Row(variant='panel'):
|
572 |
with gr.Column(scale=0.85):
|
573 |
+
elev_output = gr.Label(label='Estimated elevation (degree, w.r.t. the horizontal plane)')
|
574 |
+
vis_output = gr.Plot(label='Camera poses of the input view (red) and predicted views (blue)', elem_id="plot-out")
|
|
|
|
|
575 |
|
576 |
with gr.Column(scale=1.15):
|
577 |
gr.Markdown('Predicted multi-view images')
|
|
|
595 |
btn_retry_6 = gr.Checkbox(label='Retry view 6')
|
596 |
btn_retry_7 = gr.Checkbox(label='Retry view 7')
|
597 |
btn_retry_8 = gr.Checkbox(label='Retry view 8')
|
|
|
598 |
with gr.Row():
|
599 |
regen_view_btn = gr.Button('1. Regenerate selected view(s)', variant='secondary', visible=False)
|
600 |
regen_mesh_btn = gr.Button('2. Regenerate nearby views and mesh', variant='secondary', visible=False)
|
|
|
646 |
def on_retry_button_click(*btn_retrys):
|
647 |
any_checked = any([btn_retry for btn_retry in btn_retrys])
|
648 |
print('any_checked:', any_checked, [btn_retry for btn_retry in btn_retrys])
|
|
|
649 |
if any_checked:
|
650 |
return (gr.update(visible=True), gr.update(visible=True))
|
651 |
else:
|
652 |
return (gr.update(), gr.update())
|
|
|
653 |
# make regen_btn visible when any of the btn_retry is checked
|
654 |
for btn_retry in btn_retrys:
|
655 |
# Add the event handlers to the btn_retry buttons
|