Spaces:
Runtime error
Runtime error
Commit ·
d5a5fa0
1
Parent(s): 20241dd
Update image assets and refactor app.py for improved functionality. Added new images, removed outdated ones, and updated paths in IMAGE_PATHS. Renamed render_demo3 function to render_demonstrate for clarity. Adjusted UI styles and fixed image loading issues.
Browse files- .gitattributes +4 -0
- app.py +118 -184
- test_samples/{oxford.jpeg → arc_de_tromphe.jpeg} +2 -2
- test_samples/jesus.jpg +2 -2
- test_samples/{friends.jpg → living_room.jpg} +2 -2
- test_samples/living_room_2.jpeg +3 -0
- test_samples/open_door.jpg +2 -2
- test_samples/oxford.jpg +3 -0
.gitattributes
CHANGED
|
@@ -38,3 +38,7 @@ test_samples/oxford.jpeg filter=lfs diff=lfs merge=lfs -text
|
|
| 38 |
test_samples/changi.jpg filter=lfs diff=lfs merge=lfs -text
|
| 39 |
test_samples/friends.jpg filter=lfs diff=lfs merge=lfs -text
|
| 40 |
test_samples/jesus.jpg filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
test_samples/changi.jpg filter=lfs diff=lfs merge=lfs -text
|
| 39 |
test_samples/friends.jpg filter=lfs diff=lfs merge=lfs -text
|
| 40 |
test_samples/jesus.jpg filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
test_samples/living_room_2.jpeg filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
test_samples/living_room.jpg filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
test_samples/oxford.jpg filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
test_samples/arc_de_tromphe.jpeg filter=lfs diff=lfs merge=lfs -text
|
app.py
CHANGED
|
@@ -27,6 +27,7 @@ import glob
|
|
| 27 |
|
| 28 |
|
| 29 |
|
|
|
|
| 30 |
CONFIG_PATH = "configs/inference/inference.yaml"
|
| 31 |
CONFIG = OmegaConf.load(CONFIG_PATH)
|
| 32 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
@@ -39,12 +40,13 @@ WIDTH = 576
|
|
| 39 |
HEIGHT = 576
|
| 40 |
|
| 41 |
|
| 42 |
-
IMAGE_PATHS = ['test_samples/
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
|
|
|
| 48 |
|
| 49 |
# If no images found, create placeholders
|
| 50 |
if not IMAGE_PATHS:
|
|
@@ -52,7 +54,6 @@ if not IMAGE_PATHS:
|
|
| 52 |
"""Create placeholder images for the demo"""
|
| 53 |
images = []
|
| 54 |
for i in range(num_samples):
|
| 55 |
-
# Create a gradient image as placeholder
|
| 56 |
img = np.zeros((height, width, 3), dtype=np.uint8)
|
| 57 |
for h in range(height):
|
| 58 |
for w in range(width):
|
|
@@ -314,13 +315,13 @@ def undo_navigation(
|
|
| 314 |
|
| 315 |
|
| 316 |
|
| 317 |
-
def
|
| 318 |
s: Literal["Selection", "Generation"],
|
| 319 |
idx: int,
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
):
|
| 325 |
gr.Markdown(
|
| 326 |
"""
|
|
@@ -377,17 +378,20 @@ def render_demo3(
|
|
| 377 |
upload_btn.click(
|
| 378 |
fn=process_uploaded_image,
|
| 379 |
inputs=[upload_image],
|
| 380 |
-
outputs=[
|
| 381 |
)
|
| 382 |
|
| 383 |
gr.Markdown("### Or Choose From Our Examples")
|
| 384 |
# Define image captions
|
| 385 |
image_captions = {
|
| 386 |
-
|
| 387 |
-
'test_samples/oxford.
|
| 388 |
'test_samples/open_door.jpg': 'Bedroom Interior',
|
|
|
|
|
|
|
|
|
|
| 389 |
'test_samples/jesus.jpg': 'Jesus College',
|
| 390 |
-
'test_samples/
|
| 391 |
}
|
| 392 |
|
| 393 |
# Load all images for the gallery with captions
|
|
@@ -401,7 +405,7 @@ def render_demo3(
|
|
| 401 |
print(f"Error loading image {img_path}: {e}")
|
| 402 |
|
| 403 |
# Show image gallery for selection
|
| 404 |
-
|
| 405 |
value=gallery_images,
|
| 406 |
label="Select an Image to Start Navigation",
|
| 407 |
columns=len(gallery_images),
|
|
@@ -436,22 +440,22 @@ def render_demo3(
|
|
| 436 |
gr.Warning(f"Error starting navigation: {e}")
|
| 437 |
return "Selection", None, None, None
|
| 438 |
|
| 439 |
-
|
| 440 |
fn=start_navigation,
|
| 441 |
inputs=None,
|
| 442 |
-
outputs=[
|
| 443 |
)
|
| 444 |
|
| 445 |
case "Generation":
|
| 446 |
with gr.Row():
|
| 447 |
with gr.Column(scale=3):
|
| 448 |
with gr.Row():
|
| 449 |
-
|
| 450 |
label="Current View",
|
| 451 |
width=256,
|
| 452 |
height=256,
|
| 453 |
)
|
| 454 |
-
|
| 455 |
label="Generated Video",
|
| 456 |
width=256,
|
| 457 |
height=256,
|
|
@@ -461,7 +465,7 @@ def render_demo3(
|
|
| 461 |
show_download_button=True,
|
| 462 |
)
|
| 463 |
|
| 464 |
-
|
| 465 |
value=[],
|
| 466 |
label="Generated Frames",
|
| 467 |
columns=[6],
|
|
@@ -472,7 +476,7 @@ def render_demo3(
|
|
| 472 |
try:
|
| 473 |
selected_path = IMAGE_PATHS[idx]
|
| 474 |
result = load_image_for_navigation(selected_path)
|
| 475 |
-
|
| 476 |
except Exception as e:
|
| 477 |
print(f"Error initializing current view: {e}")
|
| 478 |
|
|
@@ -503,15 +507,15 @@ def render_demo3(
|
|
| 503 |
distance=0,
|
| 504 |
),
|
| 505 |
inputs=[
|
| 506 |
-
|
| 507 |
-
|
| 508 |
],
|
| 509 |
outputs=[
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
|
| 515 |
],
|
| 516 |
)
|
| 517 |
|
|
@@ -528,42 +532,18 @@ def render_demo3(
|
|
| 528 |
distance=0,
|
| 529 |
),
|
| 530 |
inputs=[
|
| 531 |
-
|
| 532 |
-
|
| 533 |
],
|
| 534 |
outputs=[
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
],
|
| 541 |
)
|
| 542 |
|
| 543 |
-
# gr.Button(
|
| 544 |
-
# "↑0°\nAhead",
|
| 545 |
-
# size="sm",
|
| 546 |
-
# min_width=0,
|
| 547 |
-
# variant="primary",
|
| 548 |
-
# ).click(
|
| 549 |
-
# fn=partial(
|
| 550 |
-
# navigate_video,
|
| 551 |
-
# x_angle=0,
|
| 552 |
-
# y_angle=0,
|
| 553 |
-
# distance=10,
|
| 554 |
-
# ),
|
| 555 |
-
# inputs=[
|
| 556 |
-
# demo3_current_video,
|
| 557 |
-
# demo3_current_poses,
|
| 558 |
-
# ],
|
| 559 |
-
# outputs=[
|
| 560 |
-
# demo3_current_video,
|
| 561 |
-
# demo3_current_poses,
|
| 562 |
-
# demo3_current_view,
|
| 563 |
-
# demo3_video,
|
| 564 |
-
# demo3_generated_gallery,
|
| 565 |
-
# ],
|
| 566 |
-
# )
|
| 567 |
gr.Button(
|
| 568 |
"↗10°\nTurn",
|
| 569 |
size="sm",
|
|
@@ -577,15 +557,15 @@ def render_demo3(
|
|
| 577 |
distance=0,
|
| 578 |
),
|
| 579 |
inputs=[
|
| 580 |
-
|
| 581 |
-
|
| 582 |
],
|
| 583 |
outputs=[
|
| 584 |
-
|
| 585 |
-
|
| 586 |
-
|
| 587 |
-
|
| 588 |
-
|
| 589 |
],
|
| 590 |
)
|
| 591 |
gr.Button(
|
|
@@ -601,15 +581,15 @@ def render_demo3(
|
|
| 601 |
distance=0,
|
| 602 |
),
|
| 603 |
inputs=[
|
| 604 |
-
|
| 605 |
-
|
| 606 |
],
|
| 607 |
outputs=[
|
| 608 |
-
|
| 609 |
-
|
| 610 |
-
|
| 611 |
-
|
| 612 |
-
|
| 613 |
],
|
| 614 |
)
|
| 615 |
|
|
@@ -628,15 +608,15 @@ def render_demo3(
|
|
| 628 |
distance=-10,
|
| 629 |
),
|
| 630 |
inputs=[
|
| 631 |
-
|
| 632 |
-
|
| 633 |
],
|
| 634 |
outputs=[
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
],
|
| 641 |
)
|
| 642 |
|
|
@@ -653,78 +633,30 @@ def render_demo3(
|
|
| 653 |
distance=10,
|
| 654 |
),
|
| 655 |
inputs=[
|
| 656 |
-
|
| 657 |
-
|
| 658 |
],
|
| 659 |
outputs=[
|
| 660 |
-
|
| 661 |
-
|
| 662 |
-
|
| 663 |
-
|
| 664 |
-
|
| 665 |
],
|
| 666 |
)
|
| 667 |
-
# with gr.Tab("Advanced", elem_id="advanced-controls-tab"):
|
| 668 |
-
# with gr.Group():
|
| 669 |
-
# gr.Markdown("_**Select angles and distance:**_")
|
| 670 |
-
|
| 671 |
-
# demo3_y_angle = gr.Slider(
|
| 672 |
-
# minimum=-90,
|
| 673 |
-
# maximum=90,
|
| 674 |
-
# value=0,
|
| 675 |
-
# step=10,
|
| 676 |
-
# label="Horizontal Angle",
|
| 677 |
-
# interactive=True,
|
| 678 |
-
# )
|
| 679 |
-
# demo3_x_angle = gr.Slider(
|
| 680 |
-
# minimum=-40,
|
| 681 |
-
# maximum=40,
|
| 682 |
-
# value=0,
|
| 683 |
-
# step=10,
|
| 684 |
-
# label="Vertical Angle",
|
| 685 |
-
# interactive=True,
|
| 686 |
-
# )
|
| 687 |
-
# demo3_distance = gr.Slider(
|
| 688 |
-
# minimum=-200,
|
| 689 |
-
# maximum=200,
|
| 690 |
-
# value=100,
|
| 691 |
-
# step=10,
|
| 692 |
-
# label="Distance (negative = backward)",
|
| 693 |
-
# interactive=True,
|
| 694 |
-
# )
|
| 695 |
-
|
| 696 |
-
# gr.Button(
|
| 697 |
-
# "Generate Next Move", variant="primary"
|
| 698 |
-
# ).click(
|
| 699 |
-
# fn=navigate_video,
|
| 700 |
-
# inputs=[
|
| 701 |
-
# demo3_current_video,
|
| 702 |
-
# demo3_current_poses,
|
| 703 |
-
# demo3_x_angle,
|
| 704 |
-
# demo3_y_angle,
|
| 705 |
-
# demo3_distance,
|
| 706 |
-
# ],
|
| 707 |
-
# outputs=[
|
| 708 |
-
# demo3_current_video,
|
| 709 |
-
# demo3_current_poses,
|
| 710 |
-
# demo3_current_view,
|
| 711 |
-
# demo3_video,
|
| 712 |
-
# demo3_generated_gallery,
|
| 713 |
-
# ],
|
| 714 |
-
# )
|
| 715 |
gr.Markdown("---")
|
| 716 |
with gr.Group():
|
| 717 |
gr.Markdown("_**Navigation controls:**_")
|
| 718 |
with gr.Row():
|
| 719 |
gr.Button("Undo Last Move", variant="huggingface").click(
|
| 720 |
fn=undo_navigation,
|
| 721 |
-
inputs=[
|
| 722 |
outputs=[
|
| 723 |
-
|
| 724 |
-
|
| 725 |
-
|
| 726 |
-
|
| 727 |
-
|
| 728 |
],
|
| 729 |
)
|
| 730 |
|
|
@@ -741,7 +673,7 @@ def render_demo3(
|
|
| 741 |
|
| 742 |
gr.Button("Save Camera", variant="huggingface").click(
|
| 743 |
fn=save_camera_poses,
|
| 744 |
-
inputs=[
|
| 745 |
outputs=[]
|
| 746 |
)
|
| 747 |
|
|
@@ -755,12 +687,12 @@ def render_demo3(
|
|
| 755 |
gr.Button("Choose New Image", variant="secondary").click(
|
| 756 |
fn=reset_navigation,
|
| 757 |
inputs=[],
|
| 758 |
-
outputs=[
|
| 759 |
)
|
| 760 |
|
| 761 |
|
| 762 |
# Create the Gradio Blocks
|
| 763 |
-
with gr.Blocks(theme=gr.themes.Base(primary_hue="
|
| 764 |
gr.HTML(
|
| 765 |
"""
|
| 766 |
<style>
|
|
@@ -769,10 +701,10 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
|
|
| 769 |
font-weight: bold;
|
| 770 |
}
|
| 771 |
#page-title h1 {
|
| 772 |
-
color: #
|
| 773 |
}
|
| 774 |
.task-title h2 {
|
| 775 |
-
color: #
|
| 776 |
}
|
| 777 |
.header-button-row {
|
| 778 |
gap: 4px !important;
|
|
@@ -785,7 +717,7 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
|
|
| 785 |
gap: 5px !important;
|
| 786 |
}
|
| 787 |
.header-button a {
|
| 788 |
-
border: 1px solid #
|
| 789 |
}
|
| 790 |
.header-button .button-icon {
|
| 791 |
margin-right: 8px;
|
|
@@ -808,7 +740,7 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
|
|
| 808 |
margin-top: 8px;
|
| 809 |
}
|
| 810 |
#selected-demo-button {
|
| 811 |
-
color: #
|
| 812 |
text-decoration: underline;
|
| 813 |
}
|
| 814 |
.demo-button {
|
|
@@ -828,17 +760,17 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
|
|
| 828 |
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
| 829 |
}
|
| 830 |
#navigation-gallery .gallery-item.selected {
|
| 831 |
-
border: 3px solid #
|
| 832 |
}
|
| 833 |
/* Upload image styling */
|
| 834 |
#upload-image {
|
| 835 |
border-radius: 8px;
|
| 836 |
-
border: 2px dashed #
|
| 837 |
padding: 10px;
|
| 838 |
transition: all 0.3s ease;
|
| 839 |
}
|
| 840 |
#upload-image:hover {
|
| 841 |
-
border-color: #
|
| 842 |
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
| 843 |
}
|
| 844 |
/* Box styling */
|
|
@@ -846,8 +778,28 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
|
|
| 846 |
border-radius: 10px;
|
| 847 |
margin-bottom: 20px;
|
| 848 |
padding: 15px;
|
| 849 |
-
background-color: #
|
| 850 |
-
border: 1px solid #
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 851 |
}
|
| 852 |
</style>
|
| 853 |
"""
|
|
@@ -856,9 +808,9 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
|
|
| 856 |
demo_idx = gr.State(value=3)
|
| 857 |
|
| 858 |
with gr.Sidebar():
|
| 859 |
-
gr.Markdown("# VMem: Consistent Scene Generation with Surfel
|
| 860 |
gr.Markdown(
|
| 861 |
-
"### Official Interactive Demo for [_VMem_](https://arxiv.org/abs/2502.06764)"
|
| 862 |
)
|
| 863 |
gr.Markdown("---")
|
| 864 |
gr.Markdown("#### Links ↓")
|
|
@@ -898,40 +850,22 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="teal")) as demo:
|
|
| 898 |
min_width=0,
|
| 899 |
)
|
| 900 |
gr.Markdown("---")
|
| 901 |
-
gr.Markdown("
|
| 902 |
-
|
| 903 |
-
@gr.render(inputs=[demo_idx])
|
| 904 |
-
def render_demo_tabs(idx):
|
| 905 |
-
demo_tab_button3 = gr.Button(
|
| 906 |
-
"Navigate Image",
|
| 907 |
-
size="md", elem_classes=["demo-button"], **{"elem_id": "selected-demo-button"} if idx == 3 else {}
|
| 908 |
-
).click(
|
| 909 |
-
fn=lambda: 3,
|
| 910 |
-
outputs=demo_idx
|
| 911 |
-
)
|
| 912 |
-
gr.Markdown("---")
|
| 913 |
-
gr.Markdown("#### Troubleshooting ↓")
|
| 914 |
-
with gr.Group():
|
| 915 |
-
with gr.Accordion("Error or Unexpected Results?", open=False):
|
| 916 |
-
gr.Markdown("Please try again after refreshing the page and ensure you do not click the same button multiple times.")
|
| 917 |
-
with gr.Accordion("Too Slow or No GPU Allocation?", open=False):
|
| 918 |
-
gr.Markdown(
|
| 919 |
-
"Consider running the demo locally (click the dots in the top-right corner). Alternatively, you can subscribe to Hugging Face Pro for an increased GPU quota."
|
| 920 |
-
)
|
| 921 |
|
| 922 |
|
| 923 |
-
|
| 924 |
-
|
| 925 |
-
|
| 926 |
-
|
| 927 |
|
| 928 |
-
@gr.render(inputs=[demo_idx,
|
| 929 |
def render_demo(
|
| 930 |
-
_demo_idx,
|
| 931 |
):
|
| 932 |
match _demo_idx:
|
| 933 |
case 3:
|
| 934 |
-
|
| 935 |
|
| 936 |
|
| 937 |
if __name__ == "__main__":
|
|
|
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
+
|
| 31 |
CONFIG_PATH = "configs/inference/inference.yaml"
|
| 32 |
CONFIG = OmegaConf.load(CONFIG_PATH)
|
| 33 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
|
|
| 40 |
HEIGHT = 576
|
| 41 |
|
| 42 |
|
| 43 |
+
IMAGE_PATHS = ['test_samples/oxford.jpg',
|
| 44 |
+
'test_samples/open_door.jpg',
|
| 45 |
+
'test_samples/living_room.jpg',
|
| 46 |
+
'test_samples/living_room_2.jpeg',
|
| 47 |
+
'test_samples/arc_de_tromphe.jpeg',
|
| 48 |
+
'test_samples/changi.jpg',
|
| 49 |
+
'test_samples/jesus.jpg',]
|
| 50 |
|
| 51 |
# If no images found, create placeholders
|
| 52 |
if not IMAGE_PATHS:
|
|
|
|
| 54 |
"""Create placeholder images for the demo"""
|
| 55 |
images = []
|
| 56 |
for i in range(num_samples):
|
|
|
|
| 57 |
img = np.zeros((height, width, 3), dtype=np.uint8)
|
| 58 |
for h in range(height):
|
| 59 |
for w in range(width):
|
|
|
|
| 315 |
|
| 316 |
|
| 317 |
|
| 318 |
+
def render_demonstrate(
|
| 319 |
s: Literal["Selection", "Generation"],
|
| 320 |
idx: int,
|
| 321 |
+
demonstrate_stage: gr.State,
|
| 322 |
+
demonstrate_selected_index: gr.State,
|
| 323 |
+
demonstrate_current_video: gr.State,
|
| 324 |
+
demonstrate_current_poses: gr.State
|
| 325 |
):
|
| 326 |
gr.Markdown(
|
| 327 |
"""
|
|
|
|
| 378 |
upload_btn.click(
|
| 379 |
fn=process_uploaded_image,
|
| 380 |
inputs=[upload_image],
|
| 381 |
+
outputs=[demonstrate_stage, demonstrate_selected_index, demonstrate_current_video, demonstrate_current_poses]
|
| 382 |
)
|
| 383 |
|
| 384 |
gr.Markdown("### Or Choose From Our Examples")
|
| 385 |
# Define image captions
|
| 386 |
image_captions = {
|
| 387 |
+
|
| 388 |
+
'test_samples/oxford.jpg': 'Oxford University',
|
| 389 |
'test_samples/open_door.jpg': 'Bedroom Interior',
|
| 390 |
+
'test_samples/living_room.jpg': 'Living Room',
|
| 391 |
+
'test_samples/living_room_2.jpeg': 'Living Room 2',
|
| 392 |
+
'test_samples/arc_de_tromphe.jpeg': 'Arc de Triomphe',
|
| 393 |
'test_samples/jesus.jpg': 'Jesus College',
|
| 394 |
+
'test_samples/changi.jpg': 'Changi Airport',
|
| 395 |
}
|
| 396 |
|
| 397 |
# Load all images for the gallery with captions
|
|
|
|
| 405 |
print(f"Error loading image {img_path}: {e}")
|
| 406 |
|
| 407 |
# Show image gallery for selection
|
| 408 |
+
demonstrate_image_gallery = gr.Gallery(
|
| 409 |
value=gallery_images,
|
| 410 |
label="Select an Image to Start Navigation",
|
| 411 |
columns=len(gallery_images),
|
|
|
|
| 440 |
gr.Warning(f"Error starting navigation: {e}")
|
| 441 |
return "Selection", None, None, None
|
| 442 |
|
| 443 |
+
demonstrate_image_gallery.select(
|
| 444 |
fn=start_navigation,
|
| 445 |
inputs=None,
|
| 446 |
+
outputs=[demonstrate_stage, demonstrate_selected_index, demonstrate_current_video, demonstrate_current_poses]
|
| 447 |
)
|
| 448 |
|
| 449 |
case "Generation":
|
| 450 |
with gr.Row():
|
| 451 |
with gr.Column(scale=3):
|
| 452 |
with gr.Row():
|
| 453 |
+
demonstrate_current_view = gr.Image(
|
| 454 |
label="Current View",
|
| 455 |
width=256,
|
| 456 |
height=256,
|
| 457 |
)
|
| 458 |
+
demonstrate_video = gr.Video(
|
| 459 |
label="Generated Video",
|
| 460 |
width=256,
|
| 461 |
height=256,
|
|
|
|
| 465 |
show_download_button=True,
|
| 466 |
)
|
| 467 |
|
| 468 |
+
demonstrate_generated_gallery = gr.Gallery(
|
| 469 |
value=[],
|
| 470 |
label="Generated Frames",
|
| 471 |
columns=[6],
|
|
|
|
| 476 |
try:
|
| 477 |
selected_path = IMAGE_PATHS[idx]
|
| 478 |
result = load_image_for_navigation(selected_path)
|
| 479 |
+
demonstrate_current_view.value = result["image"]
|
| 480 |
except Exception as e:
|
| 481 |
print(f"Error initializing current view: {e}")
|
| 482 |
|
|
|
|
| 507 |
distance=0,
|
| 508 |
),
|
| 509 |
inputs=[
|
| 510 |
+
demonstrate_current_video,
|
| 511 |
+
demonstrate_current_poses,
|
| 512 |
],
|
| 513 |
outputs=[
|
| 514 |
+
demonstrate_current_video,
|
| 515 |
+
demonstrate_current_poses,
|
| 516 |
+
demonstrate_current_view,
|
| 517 |
+
demonstrate_video,
|
| 518 |
+
demonstrate_generated_gallery,
|
| 519 |
],
|
| 520 |
)
|
| 521 |
|
|
|
|
| 532 |
distance=0,
|
| 533 |
),
|
| 534 |
inputs=[
|
| 535 |
+
demonstrate_current_video,
|
| 536 |
+
demonstrate_current_poses,
|
| 537 |
],
|
| 538 |
outputs=[
|
| 539 |
+
demonstrate_current_video,
|
| 540 |
+
demonstrate_current_poses,
|
| 541 |
+
demonstrate_current_view,
|
| 542 |
+
demonstrate_video,
|
| 543 |
+
demonstrate_generated_gallery,
|
| 544 |
],
|
| 545 |
)
|
| 546 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 547 |
gr.Button(
|
| 548 |
"↗10°\nTurn",
|
| 549 |
size="sm",
|
|
|
|
| 557 |
distance=0,
|
| 558 |
),
|
| 559 |
inputs=[
|
| 560 |
+
demonstrate_current_video,
|
| 561 |
+
demonstrate_current_poses,
|
| 562 |
],
|
| 563 |
outputs=[
|
| 564 |
+
demonstrate_current_video,
|
| 565 |
+
demonstrate_current_poses,
|
| 566 |
+
demonstrate_current_view,
|
| 567 |
+
demonstrate_video,
|
| 568 |
+
demonstrate_generated_gallery,
|
| 569 |
],
|
| 570 |
)
|
| 571 |
gr.Button(
|
|
|
|
| 581 |
distance=0,
|
| 582 |
),
|
| 583 |
inputs=[
|
| 584 |
+
demonstrate_current_video,
|
| 585 |
+
demonstrate_current_poses,
|
| 586 |
],
|
| 587 |
outputs=[
|
| 588 |
+
demonstrate_current_video,
|
| 589 |
+
demonstrate_current_poses,
|
| 590 |
+
demonstrate_current_view,
|
| 591 |
+
demonstrate_video,
|
| 592 |
+
demonstrate_generated_gallery,
|
| 593 |
],
|
| 594 |
)
|
| 595 |
|
|
|
|
| 608 |
distance=-10,
|
| 609 |
),
|
| 610 |
inputs=[
|
| 611 |
+
demonstrate_current_video,
|
| 612 |
+
demonstrate_current_poses,
|
| 613 |
],
|
| 614 |
outputs=[
|
| 615 |
+
demonstrate_current_video,
|
| 616 |
+
demonstrate_current_poses,
|
| 617 |
+
demonstrate_current_view,
|
| 618 |
+
demonstrate_video,
|
| 619 |
+
demonstrate_generated_gallery,
|
| 620 |
],
|
| 621 |
)
|
| 622 |
|
|
|
|
| 633 |
distance=10,
|
| 634 |
),
|
| 635 |
inputs=[
|
| 636 |
+
demonstrate_current_video,
|
| 637 |
+
demonstrate_current_poses,
|
| 638 |
],
|
| 639 |
outputs=[
|
| 640 |
+
demonstrate_current_video,
|
| 641 |
+
demonstrate_current_poses,
|
| 642 |
+
demonstrate_current_view,
|
| 643 |
+
demonstrate_video,
|
| 644 |
+
demonstrate_generated_gallery,
|
| 645 |
],
|
| 646 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
gr.Markdown("---")
|
| 648 |
with gr.Group():
|
| 649 |
gr.Markdown("_**Navigation controls:**_")
|
| 650 |
with gr.Row():
|
| 651 |
gr.Button("Undo Last Move", variant="huggingface").click(
|
| 652 |
fn=undo_navigation,
|
| 653 |
+
inputs=[demonstrate_current_video, demonstrate_current_poses],
|
| 654 |
outputs=[
|
| 655 |
+
demonstrate_current_video,
|
| 656 |
+
demonstrate_current_poses,
|
| 657 |
+
demonstrate_current_view,
|
| 658 |
+
demonstrate_video,
|
| 659 |
+
demonstrate_generated_gallery,
|
| 660 |
],
|
| 661 |
)
|
| 662 |
|
|
|
|
| 673 |
|
| 674 |
gr.Button("Save Camera", variant="huggingface").click(
|
| 675 |
fn=save_camera_poses,
|
| 676 |
+
inputs=[demonstrate_current_video, demonstrate_current_poses],
|
| 677 |
outputs=[]
|
| 678 |
)
|
| 679 |
|
|
|
|
| 687 |
gr.Button("Choose New Image", variant="secondary").click(
|
| 688 |
fn=reset_navigation,
|
| 689 |
inputs=[],
|
| 690 |
+
outputs=[demonstrate_stage, demonstrate_selected_index, demonstrate_current_video, demonstrate_current_poses]
|
| 691 |
)
|
| 692 |
|
| 693 |
|
| 694 |
# Create the Gradio Blocks
|
| 695 |
+
with gr.Blocks(theme=gr.themes.Base(primary_hue="purple")) as demo:
|
| 696 |
gr.HTML(
|
| 697 |
"""
|
| 698 |
<style>
|
|
|
|
| 701 |
font-weight: bold;
|
| 702 |
}
|
| 703 |
#page-title h1 {
|
| 704 |
+
color: #9B6B9E !important;
|
| 705 |
}
|
| 706 |
.task-title h2 {
|
| 707 |
+
color: #B19CD9 !important;
|
| 708 |
}
|
| 709 |
.header-button-row {
|
| 710 |
gap: 4px !important;
|
|
|
|
| 717 |
gap: 5px !important;
|
| 718 |
}
|
| 719 |
.header-button a {
|
| 720 |
+
border: 1px solid #9B6B9E;
|
| 721 |
}
|
| 722 |
.header-button .button-icon {
|
| 723 |
margin-right: 8px;
|
|
|
|
| 740 |
margin-top: 8px;
|
| 741 |
}
|
| 742 |
#selected-demo-button {
|
| 743 |
+
color: #B19CD9;
|
| 744 |
text-decoration: underline;
|
| 745 |
}
|
| 746 |
.demo-button {
|
|
|
|
| 760 |
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
| 761 |
}
|
| 762 |
#navigation-gallery .gallery-item.selected {
|
| 763 |
+
border: 3px solid #9B6B9E;
|
| 764 |
}
|
| 765 |
/* Upload image styling */
|
| 766 |
#upload-image {
|
| 767 |
border-radius: 8px;
|
| 768 |
+
border: 2px dashed #9B6B9E;
|
| 769 |
padding: 10px;
|
| 770 |
transition: all 0.3s ease;
|
| 771 |
}
|
| 772 |
#upload-image:hover {
|
| 773 |
+
border-color: #9B6B9E;
|
| 774 |
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
| 775 |
}
|
| 776 |
/* Box styling */
|
|
|
|
| 778 |
border-radius: 10px;
|
| 779 |
margin-bottom: 20px;
|
| 780 |
padding: 15px;
|
| 781 |
+
background-color: #9B6B9E;
|
| 782 |
+
border: 1px solid #9B6B9E;
|
| 783 |
+
}
|
| 784 |
+
/* Start Navigation button styling */
|
| 785 |
+
button[data-testid="Start Navigation"] {
|
| 786 |
+
background-color: #B19CD9 !important;
|
| 787 |
+
border-color: #B19CD9 !important;
|
| 788 |
+
color: white !important;
|
| 789 |
+
}
|
| 790 |
+
button[data-testid="Start Navigation"]:hover {
|
| 791 |
+
background-color: #9B6B9E !important;
|
| 792 |
+
border-color: #9B6B9E !important;
|
| 793 |
+
}
|
| 794 |
+
/* Override Gradio's primary button color */
|
| 795 |
+
.gradio-button.primary {
|
| 796 |
+
background-color: #B19CD9 !important;
|
| 797 |
+
border-color: #B19CD9 !important;
|
| 798 |
+
color: white !important;
|
| 799 |
+
}
|
| 800 |
+
.gradio-button.primary:hover {
|
| 801 |
+
background-color: #9B6B9E !important;
|
| 802 |
+
border-color: #9B6B9E !important;
|
| 803 |
}
|
| 804 |
</style>
|
| 805 |
"""
|
|
|
|
| 808 |
demo_idx = gr.State(value=3)
|
| 809 |
|
| 810 |
with gr.Sidebar():
|
| 811 |
+
gr.Markdown("# VMem: Consistent Video Scene Generation with Surfel-Indexed View Memory", elem_id="page-title")
|
| 812 |
gr.Markdown(
|
| 813 |
+
"### Official Interactive Demo for [_VMem_](https://arxiv.org/abs/2502.06764) that enables interactive consistent video scene generation."
|
| 814 |
)
|
| 815 |
gr.Markdown("---")
|
| 816 |
gr.Markdown("#### Links ↓")
|
|
|
|
| 850 |
min_width=0,
|
| 851 |
)
|
| 852 |
gr.Markdown("---")
|
| 853 |
+
gr.Markdown("This demo interface is adapted from the History-Guided Video Diffusion demo template. We thank the authors for their work.")
|
| 854 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 855 |
|
| 856 |
|
| 857 |
+
demonstrate_stage = gr.State(value="Selection")
|
| 858 |
+
demonstrate_selected_index = gr.State(value=None)
|
| 859 |
+
demonstrate_current_video = gr.State(value=None)
|
| 860 |
+
demonstrate_current_poses = gr.State(value=None)
|
| 861 |
|
| 862 |
+
@gr.render(inputs=[demo_idx, demonstrate_stage, demonstrate_selected_index])
|
| 863 |
def render_demo(
|
| 864 |
+
_demo_idx, _demonstrate_stage, _demonstrate_selected_index
|
| 865 |
):
|
| 866 |
match _demo_idx:
|
| 867 |
case 3:
|
| 868 |
+
render_demonstrate(_demonstrate_stage, _demonstrate_selected_index, demonstrate_stage, demonstrate_selected_index, demonstrate_current_video, demonstrate_current_poses)
|
| 869 |
|
| 870 |
|
| 871 |
if __name__ == "__main__":
|
test_samples/{oxford.jpeg → arc_de_tromphe.jpeg}
RENAMED
|
File without changes
|
test_samples/jesus.jpg
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
test_samples/{friends.jpg → living_room.jpg}
RENAMED
|
File without changes
|
test_samples/living_room_2.jpeg
ADDED
|
Git LFS Details
|
test_samples/open_door.jpg
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
test_samples/oxford.jpg
ADDED
|
Git LFS Details
|