vimdhayak commited on
Commit
dddaa32
·
verified ·
1 Parent(s): f9b8e00

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -37
app.py CHANGED
@@ -610,6 +610,150 @@ html, body, .gradio-container {
610
  box-shadow: none !important;
611
  }
612
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
613
  """
614
 
615
 
@@ -621,8 +765,7 @@ HERO_HTML = f"""
621
  <div class="hero-card">
622
  <h1>LCVC DeepFuse</h1>
623
  <h2>Brain MRI Ensemble Classifier</h2>
624
- <div class="class-chip-row">{CLASS_CHIPS_HTML}</div>
625
- </div>
626
  """
627
 
628
 
@@ -637,11 +780,10 @@ def _empty_prediction_card() -> str:
637
  <div class="pred-label">Waiting</div>
638
  <div class="pred-sub">Upload an MRI image, then run prediction.</div>
639
  <div class="metric-grid">
640
- <div class="metric"><div class="k">Input size</div><div class="v">—</div></div>
641
- <div class="metric"><div class="k">Model votes</div><div class="v">3</div></div>
642
- <div class="metric"><div class="k">Confidence</div><div class="v confidence">—</div></div>
643
- </div>
644
- </div>
645
  """
646
 
647
 
@@ -653,13 +795,12 @@ def _prediction_card(label: str, confidence: float, image: Image.Image) -> str:
653
  <div class="result-card">
654
  <div class="pred-title">Top Prediction</div>
655
  <div class="pred-label">{label}</div>
656
- <div class="pred-sub">Confidence: <b>{confidence_text}</b></div>
657
  <div class="metric-grid">
658
- <div class="metric"><div class="k">Input size</div><div class="v">{width} × {height}</div></div>
659
- <div class="metric"><div class="k">Model votes</div><div class="v">3</div></div>
660
- <div class="metric"><div class="k">Confidence</div><div class="v confidence">{confidence_text}</div></div>
661
- </div>
662
- </div>
663
  """
664
 
665
 
@@ -683,10 +824,8 @@ def _probabilities_card(probabilities: dict[str, float] | None = None, top_class
683
  <div class="prob-item{top_class_name}">
684
  <div class="prob-head">
685
  <span class="prob-label">{html.escape(display)}</span>
686
- <span class="prob-percent">{percent:.2f}%</span>
687
- </div>
688
- <div class="prob-track"><div class="prob-fill" style="width:{percent:.4f}%"></div></div>
689
- </div>
690
  """
691
  )
692
 
@@ -706,13 +845,11 @@ def _empty_details_card() -> str:
706
  <div class="member-row">
707
  <div>
708
  <div class="member-name">Waiting for image</div>
709
- <div class="member-meta">EfficientNet-B0 + MobileNetV3-Small ensemble</div>
710
- </div>
711
- <div class="detail-pill"><div class="detail-key">Predicts</div><div class="detail-value">—</div></div>
712
- <div class="detail-pill"><div class="detail-key">Confidence</div><div class="detail-value">—</div></div>
713
- <div class="detail-pill"><div class="detail-key">Weighted vote</div><div class="detail-value accent">—</div></div>
714
- </div>
715
- </div>
716
  """
717
 
718
 
@@ -733,21 +870,17 @@ def _details_card(member_df) -> str:
733
  <div class="member-row">
734
  <div>
735
  <div class="member-name">{member}</div>
736
- <div class="member-meta">Ensemble weight: {weight * 100.0:.2f}%</div>
737
- </div>
738
  <div class="detail-pill">
739
  <div class="detail-key">Predicts</div>
740
- <div class="detail-value">{pred}</div>
741
- </div>
742
  <div class="detail-pill">
743
  <div class="detail-key">Confidence</div>
744
- <div class="detail-value">{conf * 100.0:.2f}%</div>
745
- </div>
746
  <div class="detail-pill">
747
  <div class="detail-key">Weighted vote</div>
748
  <div class="detail-value accent">{weighted_vote * 100.0:.2f}%</div>
749
- <div class="vote-track"><div class="vote-fill" style="width:{weighted_vote * 100.0:.4f}%"></div></div>
750
- </div>
751
  </div>
752
  """
753
  )
@@ -794,7 +927,7 @@ with gr.Blocks(
794
  label="Upload MRI Image",
795
  show_label=False,
796
  type="pil",
797
- height=520,
798
  sources=["upload", "clipboard"],
799
  elem_id="mri_upload",
800
  )
@@ -826,9 +959,5 @@ with gr.Blocks(
826
  inputs=[image_input, heatmap_toggle],
827
  outputs=[prediction_html, probabilities_html, details_html, heatmap_output],
828
  )
829
-
830
- gr.HTML('<div class="footer-note">Research prototype only — not for clinical diagnosis.</div>')
831
-
832
-
833
  if __name__ == "__main__":
834
  demo.queue(max_size=16).launch()
 
610
  box-shadow: none !important;
611
  }
612
 
613
+
614
+
615
+ /* FINAL UI STABILIZER
616
+ Keep Gradio upload/clipboard controls visible. Do not clip the image component internals. */
617
+ .gradio-container {
618
+ background: #0b1220 !important;
619
+ }
620
+
621
+ .glass-card {
622
+ overflow: visible !important;
623
+ }
624
+
625
+ /* Upload and heatmap components should be full-width but not internally clipped. */
626
+ #mri_upload,
627
+ #heatmap_preview {
628
+ width: 100% !important;
629
+ max-width: 100% !important;
630
+ overflow: visible !important;
631
+ background: transparent !important;
632
+ border: 0 !important;
633
+ box-shadow: none !important;
634
+ }
635
+
636
+ /* Let the native Gradio controls breathe. This fixes the hidden upload/paste buttons. */
637
+ #mri_upload > div,
638
+ #heatmap_preview > div,
639
+ #mri_upload .wrap,
640
+ #heatmap_preview .wrap,
641
+ #mri_upload .block,
642
+ #heatmap_preview .block,
643
+ #mri_upload .form,
644
+ #heatmap_preview .form {
645
+ width: 100% !important;
646
+ max-width: 100% !important;
647
+ min-width: 0 !important;
648
+ overflow: visible !important;
649
+ background: transparent !important;
650
+ box-shadow: none !important;
651
+ }
652
+
653
+ /* The source buttons/tabs: upload + paste/clipboard. */
654
+ #mri_upload button,
655
+ #mri_upload .tabs button,
656
+ #mri_upload [role="tab"],
657
+ #mri_upload [data-testid="tab"],
658
+ #mri_upload .tabitem button,
659
+ #heatmap_preview button,
660
+ #heatmap_preview .tabs button,
661
+ #heatmap_preview [role="tab"],
662
+ #heatmap_preview [data-testid="tab"] {
663
+ min-height: 40px !important;
664
+ height: auto !important;
665
+ padding: 9px 16px !important;
666
+ border-radius: 14px !important;
667
+ background: rgba(30, 41, 59, .95) !important;
668
+ color: #e5e7eb !important;
669
+ border: 1px solid rgba(148, 163, 184, .30) !important;
670
+ opacity: 1 !important;
671
+ visibility: visible !important;
672
+ transform: none !important;
673
+ position: relative !important;
674
+ z-index: 20 !important;
675
+ }
676
+
677
+ /* Source-selector strip: visible, compact, and above the drop area. */
678
+ #mri_upload .tabs,
679
+ #mri_upload [role="tablist"],
680
+ #mri_upload .tab-nav,
681
+ #heatmap_preview .tabs,
682
+ #heatmap_preview [role="tablist"],
683
+ #heatmap_preview .tab-nav {
684
+ display: flex !important;
685
+ visibility: visible !important;
686
+ opacity: 1 !important;
687
+ gap: 10px !important;
688
+ padding: 0 0 12px 0 !important;
689
+ margin: 0 !important;
690
+ background: transparent !important;
691
+ border: 0 !important;
692
+ position: relative !important;
693
+ z-index: 25 !important;
694
+ }
695
+
696
+ /* Main image/drop area. This is the visible card body, not a second hidden background. */
697
+ #mri_upload .image-container,
698
+ #mri_upload .upload-container,
699
+ #mri_upload [data-testid="image"],
700
+ #mri_upload .empty {
701
+ width: 100% !important;
702
+ max-width: 100% !important;
703
+ min-height: 500px !important;
704
+ height: 500px !important;
705
+ overflow: hidden !important;
706
+ border-radius: 24px !important;
707
+ background: linear-gradient(180deg, #111827 0%, #060b16 100%) !important;
708
+ border: 1px solid rgba(148, 163, 184, .28) !important;
709
+ box-shadow: none !important;
710
+ }
711
+
712
+ #heatmap_preview .image-container,
713
+ #heatmap_preview .upload-container,
714
+ #heatmap_preview [data-testid="image"],
715
+ #heatmap_preview .empty {
716
+ width: 100% !important;
717
+ max-width: 100% !important;
718
+ min-height: 430px !important;
719
+ height: 430px !important;
720
+ overflow: hidden !important;
721
+ border-radius: 24px !important;
722
+ background: linear-gradient(180deg, #111827 0%, #060b16 100%) !important;
723
+ border: 1px solid rgba(148, 163, 184, .28) !important;
724
+ box-shadow: none !important;
725
+ }
726
+
727
+ #mri_upload img,
728
+ #heatmap_preview img {
729
+ width: 100% !important;
730
+ height: 100% !important;
731
+ object-fit: contain !important;
732
+ border-radius: 24px !important;
733
+ background: #050816 !important;
734
+ }
735
+
736
+ /* Do not allow toolbars to be pushed down and hidden. */
737
+ #mri_upload .file-preview,
738
+ #mri_upload .file-preview-holder,
739
+ #mri_upload .file-preview-wrapper,
740
+ #mri_upload .thumbnail-item,
741
+ #heatmap_preview .file-preview,
742
+ #heatmap_preview .file-preview-holder,
743
+ #heatmap_preview .file-preview-wrapper {
744
+ overflow: visible !important;
745
+ background: transparent !important;
746
+ border: 0 !important;
747
+ box-shadow: none !important;
748
+ }
749
+
750
+ /* Remove empty disclaimer rows if a blank HTML remains. */
751
+ .disclaimer,
752
+ .prototype-note,
753
+ .research-note {
754
+ display: none !important;
755
+ }
756
+
757
  """
758
 
759
 
 
765
  <div class="hero-card">
766
  <h1>LCVC DeepFuse</h1>
767
  <h2>Brain MRI Ensemble Classifier</h2>
768
+ <div class="class-chip-row">{CLASS_CHIPS_HTML}
 
769
  """
770
 
771
 
 
780
  <div class="pred-label">Waiting</div>
781
  <div class="pred-sub">Upload an MRI image, then run prediction.</div>
782
  <div class="metric-grid">
783
+ <div class="metric"><div class="k">Input size</div><div class="v">—
784
+ <div class="metric"><div class="k">Model votes</div><div class="v">3
785
+ <div class="metric"><div class="k">Confidence</div><div class="v confidence">—
786
+
 
787
  """
788
 
789
 
 
795
  <div class="result-card">
796
  <div class="pred-title">Top Prediction</div>
797
  <div class="pred-label">{label}</div>
798
+ <div class="pred-sub">Confidence: <b>{confidence_text}
799
  <div class="metric-grid">
800
+ <div class="metric"><div class="k">Input size</div><div class="v">{width} × {height}
801
+ <div class="metric"><div class="k">Model votes</div><div class="v">3
802
+ <div class="metric"><div class="k">Confidence</div><div class="v confidence">{confidence_text}
803
+
 
804
  """
805
 
806
 
 
824
  <div class="prob-item{top_class_name}">
825
  <div class="prob-head">
826
  <span class="prob-label">{html.escape(display)}</span>
827
+ <span class="prob-percent">{percent:.2f}%
828
+ <div class="prob-track">
 
 
829
  """
830
  )
831
 
 
845
  <div class="member-row">
846
  <div>
847
  <div class="member-name">Waiting for image</div>
848
+ <div class="member-meta">EfficientNet-B0 + MobileNetV3-Small ensemble
849
+ <div class="detail-pill"><div class="detail-key">Predicts</div><div class="detail-value">—
850
+ <div class="detail-pill"><div class="detail-key">Confidence</div><div class="detail-value">—
851
+ <div class="detail-pill"><div class="detail-key">Weighted vote</div><div class="detail-value accent">—
852
+
 
 
853
  """
854
 
855
 
 
870
  <div class="member-row">
871
  <div>
872
  <div class="member-name">{member}</div>
873
+ <div class="member-meta">Ensemble weight: {weight * 100.0:.2f}%
 
874
  <div class="detail-pill">
875
  <div class="detail-key">Predicts</div>
876
+ <div class="detail-value">{pred}
 
877
  <div class="detail-pill">
878
  <div class="detail-key">Confidence</div>
879
+ <div class="detail-value">{conf * 100.0:.2f}%
 
880
  <div class="detail-pill">
881
  <div class="detail-key">Weighted vote</div>
882
  <div class="detail-value accent">{weighted_vote * 100.0:.2f}%</div>
883
+ <div class="vote-track">
 
884
  </div>
885
  """
886
  )
 
927
  label="Upload MRI Image",
928
  show_label=False,
929
  type="pil",
930
+ height=540,
931
  sources=["upload", "clipboard"],
932
  elem_id="mri_upload",
933
  )
 
959
  inputs=[image_input, heatmap_toggle],
960
  outputs=[prediction_html, probabilities_html, details_html, heatmap_output],
961
  )
 
 
 
 
962
  if __name__ == "__main__":
963
  demo.queue(max_size=16).launch()