dennny123 commited on
Commit
42aaf32
·
verified ·
1 Parent(s): 1f3d381

Minimal B&W UI: restore teaser image, default gradio theme

Browse files
Files changed (1) hide show
  1. app.py +67 -151
app.py CHANGED
@@ -469,168 +469,85 @@ def _build_startup_markdown() -> str:
469
  return "\n".join([f"- {note}" for note in STARTUP_NOTES])
470
 
471
 
472
- CSS = """
473
- :root {
474
- --lb-bg: #0b0d12;
475
- --lb-panel: #12151c;
476
- --lb-panel-2: #161a23;
477
- --lb-border: #232836;
478
- --lb-text: #e6e8ee;
479
- --lb-muted: #8a93a6;
480
- --lb-accent: #6366f1;
481
- --lb-accent-2: #22d3ee;
482
  }
483
- .gradio-container {
484
- background: var(--lb-bg) !important;
485
- color: var(--lb-text) !important;
486
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
487
- }
488
- .shell {
489
- max-width: 1200px;
490
- margin: 0 auto;
491
- padding: 8px 4px 32px;
492
- }
493
- .hero {
494
- display: flex;
495
- flex-direction: column;
496
- gap: 6px;
497
- padding: 28px 4px 20px;
498
- border-bottom: 1px solid var(--lb-border);
499
- margin-bottom: 20px;
500
- }
501
- .hero .eyebrow {
502
- font-size: 11px;
503
- letter-spacing: 0.14em;
504
- text-transform: uppercase;
505
- color: var(--lb-accent-2);
506
- font-weight: 600;
507
- }
508
- .hero h1 {
509
- margin: 0;
510
- font-size: 34px;
511
- font-weight: 700;
512
- letter-spacing: -0.02em;
513
- background: linear-gradient(90deg, #ffffff 0%, #a5b4fc 100%);
514
- -webkit-background-clip: text;
515
- -webkit-text-fill-color: transparent;
516
- background-clip: text;
517
- }
518
- .hero p {
519
- margin: 4px 0 0;
520
- color: var(--lb-muted);
521
- font-size: 15px;
522
- max-width: 640px;
523
- line-height: 1.5;
524
- }
525
- .panel, .gr-panel, .gradio-container .gr-box {
526
- background: var(--lb-panel) !important;
527
- border: 1px solid var(--lb-border) !important;
528
- border-radius: 14px !important;
529
- }
530
- .section-title {
531
- font-size: 12px;
532
- letter-spacing: 0.1em;
533
- text-transform: uppercase;
534
- color: var(--lb-muted);
535
- font-weight: 600;
536
- margin: 4px 0 8px 2px;
537
- }
538
- button.primary, .gradio-container button.primary {
539
- background: linear-gradient(135deg, var(--lb-accent) 0%, #8b5cf6 100%) !important;
540
- border: none !important;
541
- color: #fff !important;
542
- font-weight: 600 !important;
543
- font-size: 15px !important;
544
- padding: 12px 20px !important;
545
- border-radius: 10px !important;
546
- box-shadow: 0 4px 14px rgba(99, 102, 241, 0.35) !important;
547
- transition: transform 0.15s ease, box-shadow 0.15s ease !important;
548
- }
549
- button.primary:hover {
550
- transform: translateY(-1px);
551
- box-shadow: 0 6px 20px rgba(99, 102, 241, 0.5) !important;
552
- }
553
- .startup-notes {
554
- font-size: 12px;
555
- color: var(--lb-muted);
556
- padding: 8px 12px;
557
- background: var(--lb-panel-2);
558
- border-radius: 8px;
559
- border: 1px solid var(--lb-border);
560
  }
 
561
  """
562
 
563
 
564
  _eager_load_default_model()
565
 
566
 
567
- with gr.Blocks(
568
- css=CSS,
569
- theme=gr.themes.Base(
570
- primary_hue="indigo",
571
- secondary_hue="cyan",
572
- neutral_hue="slate",
573
- font=[gr.themes.GoogleFont("Inter"), "system-ui", "sans-serif"],
574
- ),
575
- title="LingBot 3D",
576
- ) as demo:
577
- gr.HTML("<div class='shell'>")
578
- gr.HTML(
579
- """
580
- <div class="hero">
581
- <span class="eyebrow">Video 3D Reconstruction</span>
582
- <h1>LingBot 3D</h1>
583
- <p>Upload a short clip and get back a navigable 3D scene. Powered by the LingBot-Map checkpoint, exported as GLB plus a downloadable results bundle.</p>
584
- </div>
585
- """
586
- )
587
-
588
- startup_md = _build_startup_markdown()
589
- if startup_md:
590
- gr.Markdown(startup_md, elem_classes=["startup-notes"])
591
-
592
- with gr.Row(equal_height=False):
593
- with gr.Column(scale=5, min_width=360):
594
- gr.HTML("<div class='section-title'>1. Input</div>")
595
- video_file = gr.Video(
596
- label="Short video clip",
597
- sources=["upload"],
598
- format="mp4",
599
- height=260,
600
- )
601
 
602
- with gr.Accordion("Sampling & reconstruction settings", open=False):
603
- with gr.Row():
604
- fps = gr.Slider(minimum=1, maximum=12, step=1, value=DEFAULT_FPS, label="Sampling FPS")
605
- max_frames = gr.Slider(minimum=2, maximum=MAX_FRAMES_HARD_LIMIT, step=1, value=DEFAULT_MAX_FRAMES, label="Max frames")
606
- with gr.Row():
607
- num_scale_frames = gr.Slider(minimum=1, maximum=8, step=1, value=DEFAULT_SCALE_FRAMES, label="Scale frames")
608
- keyframe_interval = gr.Slider(minimum=1, maximum=8, step=1, value=DEFAULT_KEYFRAME_INTERVAL, label="Keyframe interval")
609
- conf_percentile = gr.Slider(
610
- minimum=0,
611
- maximum=90,
612
- step=5,
613
- value=DEFAULT_CONF_PERCENTILE,
614
- label="GLB confidence percentile",
615
- info="Higher = fewer, more confident points",
 
 
 
 
616
  )
617
 
618
- run_button = gr.Button("Build 3D Scene", variant="primary", size="lg")
619
- status_markdown = gr.Markdown()
620
 
621
- with gr.Column(scale=7, min_width=420):
622
- gr.HTML("<div class='section-title'>2. Output</div>")
623
- model_preview = gr.Model3D(
624
- label="3D preview",
625
- display_mode="point_cloud",
626
- clear_color=[0.04, 0.05, 0.07, 1.0],
627
- height=420,
628
- )
629
  with gr.Row():
630
- preview_image = gr.Image(label="Frame preview", interactive=False, height=180)
631
- artifact_file = gr.File(label="Download results bundle")
632
- with gr.Accordion("Run summary", open=False):
633
- summary_json = gr.JSON(label=None)
 
 
 
 
 
 
 
 
 
 
 
 
 
634
 
635
  run_button.click(
636
  fn=reconstruct_scene,
@@ -651,10 +568,9 @@ with gr.Blocks(
651
  ],
652
  show_progress="full",
653
  )
654
- gr.HTML("</div>")
655
 
656
  demo.queue(default_concurrency_limit=1)
657
 
658
 
659
  if __name__ == "__main__":
660
- demo.launch()
 
469
  return "\n".join([f"- {note}" for note in STARTUP_NOTES])
470
 
471
 
472
+ css = """
473
+ #container {
474
+ max-width: 1200px;
475
+ margin: 0 auto;
 
 
 
 
 
 
476
  }
477
+ .teaser img {
478
+ max-height: 260px !important;
479
+ object-fit: cover !important;
480
+ border-radius: 8px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  }
482
+ footer {display: none !important;}
483
  """
484
 
485
 
486
  _eager_load_default_model()
487
 
488
 
489
+ with gr.Blocks(title="LingBot 3D") as demo:
490
+ with gr.Column(elem_id="container"):
491
+ gr.Image(
492
+ value=str(ROOT / "assets" / "teaser.png"),
493
+ show_label=False,
494
+ show_download_button=False,
495
+ show_fullscreen_button=False,
496
+ interactive=False,
497
+ container=False,
498
+ elem_classes=["teaser"],
499
+ )
500
+ gr.Markdown("# LingBot 3D")
501
+ gr.Markdown(
502
+ "Upload a short video clip and get back a navigable 3D scene. "
503
+ "Powered by the LingBot-Map checkpoint, exported as a GLB plus a downloadable results bundle."
504
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
 
506
+ startup_md = _build_startup_markdown()
507
+ if startup_md:
508
+ gr.Markdown(startup_md)
509
+
510
+ with gr.Row():
511
+ with gr.Column():
512
+ video_file = gr.Video(
513
+ label="Input video",
514
+ sources=["upload"],
515
+ format="mp4",
516
+ height=380,
517
+ )
518
+ with gr.Column():
519
+ model_preview = gr.Model3D(
520
+ label="3D preview",
521
+ display_mode="point_cloud",
522
+ clear_color=[1.0, 1.0, 1.0, 1.0],
523
+ height=380,
524
  )
525
 
526
+ run_button = gr.Button("Build 3D Scene", variant="primary")
527
+ status_markdown = gr.Markdown()
528
 
529
+ with gr.Accordion("Sampling & reconstruction settings", open=False):
530
+ with gr.Row():
531
+ fps = gr.Slider(minimum=1, maximum=12, step=1, value=DEFAULT_FPS, label="Sampling FPS")
532
+ max_frames = gr.Slider(minimum=2, maximum=MAX_FRAMES_HARD_LIMIT, step=1, value=DEFAULT_MAX_FRAMES, label="Max frames")
 
 
 
 
533
  with gr.Row():
534
+ num_scale_frames = gr.Slider(minimum=1, maximum=8, step=1, value=DEFAULT_SCALE_FRAMES, label="Scale frames")
535
+ keyframe_interval = gr.Slider(minimum=1, maximum=8, step=1, value=DEFAULT_KEYFRAME_INTERVAL, label="Keyframe interval")
536
+ conf_percentile = gr.Slider(
537
+ minimum=0,
538
+ maximum=90,
539
+ step=5,
540
+ value=DEFAULT_CONF_PERCENTILE,
541
+ label="GLB confidence percentile",
542
+ info="Higher = fewer, more confident points",
543
+ )
544
+
545
+ with gr.Row():
546
+ preview_image = gr.Image(label="Frame preview", interactive=False, height=200)
547
+ artifact_file = gr.File(label="Download results bundle")
548
+
549
+ with gr.Accordion("Run summary", open=False):
550
+ summary_json = gr.JSON(label=None)
551
 
552
  run_button.click(
553
  fn=reconstruct_scene,
 
568
  ],
569
  show_progress="full",
570
  )
 
571
 
572
  demo.queue(default_concurrency_limit=1)
573
 
574
 
575
  if __name__ == "__main__":
576
+ demo.launch(css=css)