MuhammadAdil63 commited on
Commit
b501a90
Β·
1 Parent(s): 9a9e768

Video Uploading Default

Browse files
Files changed (1) hide show
  1. app.py +42 -11
app.py CHANGED
@@ -128,6 +128,30 @@ CONFIG = {
128
  "DEVICE" : "cuda:0" if torch.cuda.is_available() else "cpu",
129
  }
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  # ─────────────────────────────────────────────────────────────────────────────
132
  # ITU LOGO β€” encode to base64 for embedding in HTML
133
  # Place ITULog.png in the same directory as this script.
@@ -748,15 +772,15 @@ def _load_yolo():
748
  f"YOLOv8 checkpoint not found:\n{ckpt}\n"
749
  f"Check HF_TOKEN secret and repo MuhammadAdil63/angio-ai-checkpoints"
750
  )
751
- print(f"[YOLO] Loading checkpoint: {ckpt}")
752
  try:
753
  import torch.serialization
754
  from ultralytics.nn.tasks import SegmentationModel
755
  torch.serialization.add_safe_globals([SegmentationModel])
756
  except Exception as _e:
757
- print(f"[YOLO] safe_globals warning: {_e}")
758
  _yolo_model = YOLO(ckpt)
759
- print(f"[YOLO] Model loaded OK")
760
 
761
 
762
  def run_yolo_seg(frame_rgb: np.ndarray, seg_conf: float) -> np.ndarray:
@@ -793,7 +817,7 @@ def run_yolo_seg(frame_rgb: np.ndarray, seg_conf: float) -> np.ndarray:
793
  verbose = False,
794
  )
795
  except Exception as e:
796
- print(f"[YOLO] predict() failed: {e}")
797
  return np.zeros((512, 512), dtype=np.uint8)
798
 
799
  result = results[0]
@@ -801,7 +825,7 @@ def run_yolo_seg(frame_rgb: np.ndarray, seg_conf: float) -> np.ndarray:
801
  seg_map = np.zeros((h, w), dtype=np.uint8)
802
 
803
  if result.masks is None or result.boxes is None:
804
- print("[YOLO] No masks returned -- check conf threshold or checkpoint.")
805
  return seg_map
806
 
807
  masks = result.masks.data.cpu().numpy() # (N, Hm, Wm) float32
@@ -823,9 +847,9 @@ def run_yolo_seg(frame_rgb: np.ndarray, seg_conf: float) -> np.ndarray:
823
  n_written += int(binary.sum())
824
 
825
  detected_cls = [_YOLO_CLASS_NAMES[min(int(c) + 1, 25)] for c in cls_ids]
826
- print(f"[YOLO] Detections: {len(cls_ids)} | classes: {detected_cls} | "
827
  f"vessel px: {n_written} ({100 * n_written / (h * w):.1f}%)")
828
- print(f"[YOLO] seg_map unique labels: {np.unique(seg_map)}")
829
  return seg_map
830
 
831
  # ─────────────────────────────────────────────────────────────────────────────
@@ -1510,8 +1534,10 @@ with gr.Blocks(css=CSS, title="Angio AI") as demo:
1510
  video_input = gr.Video(
1511
  label="Upload XCA video (mp4 / avi / dicom-wrapped)",
1512
  elem_id="upload-zone",
1513
- height=240,
1514
  )
 
 
1515
  gr.HTML('</div>')
1516
 
1517
  gr.HTML('<div class="card"><div class="card-title">Model controls</div>')
@@ -1540,7 +1566,7 @@ with gr.Blocks(css=CSS, title="Angio AI") as demo:
1540
  <ol style="font-size:13px;color:#1a2533;line-height:1.9;padding-left:16px">
1541
  <li>Best frame extracted from video</li>
1542
  <li>Stenosis detection β€” Mask2Former</li>
1543
- <li>Coronary segmentation β€” YOLOv8m-seg (26-class)</li>
1544
  <li>Binary vessel mask β€” ResUNet</li>
1545
  <li>FFR estimation β€” QFR v4</li>
1546
  <li>SYNTAX score computation</li>
@@ -1592,8 +1618,8 @@ with gr.Blocks(css=CSS, title="Angio AI") as demo:
1592
 
1593
  with gr.Row():
1594
  with gr.Column():
1595
- gr.HTML('<div class="card-title" style="margin-bottom:6px">Coronary segmentation (YOLOv8m-seg)</div>')
1596
- seg_out = gr.Image(label="26-class overlay", height=300)
1597
  with gr.Column():
1598
  gr.HTML('<div class="card-title" style="margin-bottom:6px">FFR analysis</div>')
1599
  ffr_out = gr.Image(label="FFR pipeline output", height=300)
@@ -1616,6 +1642,11 @@ with gr.Blocks(css=CSS, title="Angio AI") as demo:
1616
  def run_and_switch(video, sc, sg, px):
1617
  return analyse(video, sc, sg, px)
1618
 
 
 
 
 
 
1619
  btn_analyse.click(
1620
  fn=run_and_switch,
1621
  inputs=[video_input, sten_conf, seg_conf, px_per_mm],
 
128
  "DEVICE" : "cuda:0" if torch.cuda.is_available() else "cpu",
129
  }
130
 
131
+ # ── Demo videos (hosted in HF Hub model repo alongside checkpoints) ──────────
132
+ # Upload your two XCA demo videos to MuhammadAdil63/angio-ai-checkpoints as:
133
+ # demo_video_1.mp4
134
+ # demo_video_2.mp4
135
+ # The buttons below download and load them automatically.
136
+ DEMO_VIDEO_1_NAME = "demo_video_1.mp4"
137
+ DEMO_VIDEO_2_NAME = "demo_video_2.mp4"
138
+
139
+ def _get_demo_video(filename: str) -> str:
140
+ """Download demo video from HF Hub and return local path."""
141
+ try:
142
+ from huggingface_hub import hf_hub_download
143
+ path = hf_hub_download(
144
+ repo_id = "MuhammadAdil63/angio-ai-checkpoints",
145
+ filename = filename,
146
+ repo_type= "model",
147
+ token = os.environ.get("HF_TOKEN"),
148
+ )
149
+ return path
150
+ except Exception as e:
151
+ print(f"[DEMO] Could not load {filename}: {e}")
152
+ return None
153
+
154
+
155
  # ─────────────────────────────────────────────────────────────────────────────
156
  # ITU LOGO β€” encode to base64 for embedding in HTML
157
  # Place ITULog.png in the same directory as this script.
 
772
  f"YOLOv8 checkpoint not found:\n{ckpt}\n"
773
  f"Check HF_TOKEN secret and repo MuhammadAdil63/angio-ai-checkpoints"
774
  )
775
+ print(f"[SEG] Loading checkpoint: {ckpt}")
776
  try:
777
  import torch.serialization
778
  from ultralytics.nn.tasks import SegmentationModel
779
  torch.serialization.add_safe_globals([SegmentationModel])
780
  except Exception as _e:
781
+ print(f"[SEG] safe_globals warning: {_e}")
782
  _yolo_model = YOLO(ckpt)
783
+ print(f"[SEG] Model loaded OK")
784
 
785
 
786
  def run_yolo_seg(frame_rgb: np.ndarray, seg_conf: float) -> np.ndarray:
 
817
  verbose = False,
818
  )
819
  except Exception as e:
820
+ print(f"[SEG] predict() failed: {e}")
821
  return np.zeros((512, 512), dtype=np.uint8)
822
 
823
  result = results[0]
 
825
  seg_map = np.zeros((h, w), dtype=np.uint8)
826
 
827
  if result.masks is None or result.boxes is None:
828
+ print("[SEG] No masks returned -- check conf threshold or checkpoint.")
829
  return seg_map
830
 
831
  masks = result.masks.data.cpu().numpy() # (N, Hm, Wm) float32
 
847
  n_written += int(binary.sum())
848
 
849
  detected_cls = [_YOLO_CLASS_NAMES[min(int(c) + 1, 25)] for c in cls_ids]
850
+ print(f"[SEG] Detections: {len(cls_ids)} | classes: {detected_cls} | "
851
  f"vessel px: {n_written} ({100 * n_written / (h * w):.1f}%)")
852
+ print(f"[SEG] seg_map unique labels: {np.unique(seg_map)}")
853
  return seg_map
854
 
855
  # ─────────────────────────────────────────────────────────────────────────────
 
1534
  video_input = gr.Video(
1535
  label="Upload XCA video (mp4 / avi / dicom-wrapped)",
1536
  elem_id="upload-zone",
1537
+ height=220,
1538
  )
1539
+ btn_demo1 = gr.Button("β–Ά XCA Video Run", variant="secondary", size="sm")
1540
+ gr.HTML('<div style="font-size:11px;color:#7a9ab6;margin:4px 0 8px 2px">Click to load the demo XCA video, or upload your own above.</div>')
1541
  gr.HTML('</div>')
1542
 
1543
  gr.HTML('<div class="card"><div class="card-title">Model controls</div>')
 
1566
  <ol style="font-size:13px;color:#1a2533;line-height:1.9;padding-left:16px">
1567
  <li>Best frame extracted from video</li>
1568
  <li>Stenosis detection β€” Mask2Former</li>
1569
+ <li>Coronary segmentation β€” 26-class anatomy labelling</li>
1570
  <li>Binary vessel mask β€” ResUNet</li>
1571
  <li>FFR estimation β€” QFR v4</li>
1572
  <li>SYNTAX score computation</li>
 
1618
 
1619
  with gr.Row():
1620
  with gr.Column():
1621
+ gr.HTML('<div class="card-title" style="margin-bottom:6px">Coronary segmentation (26-class)</div>')
1622
+ seg_out = gr.Image(label="26-class coronary overlay", height=300)
1623
  with gr.Column():
1624
  gr.HTML('<div class="card-title" style="margin-bottom:6px">FFR analysis</div>')
1625
  ffr_out = gr.Image(label="FFR pipeline output", height=300)
 
1642
  def run_and_switch(video, sc, sg, px):
1643
  return analyse(video, sc, sg, px)
1644
 
1645
+ def load_demo1():
1646
+ return _get_demo_video(DEMO_VIDEO_1_NAME)
1647
+
1648
+ btn_demo1.click(fn=load_demo1, inputs=[], outputs=[video_input])
1649
+
1650
  btn_analyse.click(
1651
  fn=run_and_switch,
1652
  inputs=[video_input, sten_conf, seg_conf, px_per_mm],