faceless-void commited on
Commit
6511458
Β·
verified Β·
1 Parent(s): b51bfb1

MIST-only gallery with GT, inline styles, remove BCI references

Browse files
Files changed (2) hide show
  1. app.py +14 -13
  2. gallery/metadata.json +0 -80
app.py CHANGED
@@ -244,23 +244,22 @@ def _make_gallery_label(key, entry):
244
 
245
 
246
  def show_gallery(display_name, gallery, name_map):
247
- """Show a gallery example by its display name. Only model-generated outputs shown."""
248
  key = name_map.get(display_name)
249
  if not key or not gallery or key not in gallery:
250
- return None, None, None, None, None, ""
251
  entry = gallery[key]
252
  base = GALLERY_DIR / "images"
253
- # Only show H&E input and model-generated stains (no ground truth β€” licensing)
254
  he = Image.open(base / entry["he"]).convert("RGB") if "he" in entry else None
 
255
  gen_her2 = Image.open(base / entry["gen_her2"]).convert("RGB") if "gen_her2" in entry else None
256
  gen_ki67 = Image.open(base / entry["gen_ki67"]).convert("RGB") if "gen_ki67" in entry else None
257
  gen_er = Image.open(base / entry["gen_er"]).convert("RGB") if "gen_er" in entry else None
258
  gen_pr = Image.open(base / entry["gen_pr"]).convert("RGB") if "gen_pr" in entry else None
259
 
260
- source = entry.get("source", "Unknown")
261
  gt_stain = entry.get("gt_stain", "Unknown")
262
- info = f"**Source:** {source} | **Original IHC stain:** {gt_stain}"
263
- return he, gen_her2, gen_ki67, gen_er, gen_pr, info
264
 
265
 
266
  # ── Build Gradio App ─────────────────────────────────────────────────
@@ -307,7 +306,7 @@ with gr.Blocks(title="UNIStainNet -- Virtual IHC Staining") as demo:
307
  else:
308
  gr.Markdown(
309
  "Browse pre-computed virtual staining results -- **no GPU required**. "
310
- "Each example shows the H&E input and all 4 generated IHC stains from our unified model."
311
  )
312
  gallery_dropdown = gr.Dropdown(
313
  choices=gallery_display_names,
@@ -316,10 +315,12 @@ with gr.Blocks(title="UNIStainNet -- Virtual IHC Staining") as demo:
316
  )
317
  gallery_info_box = gr.Markdown(value="")
318
 
319
- gr.Markdown("### H&E Input")
320
- gal_he = gr.Image(type="pil", label="H&E Input", height=300)
 
 
321
 
322
- gr.Markdown("### Generated IHC Stains")
323
  with gr.Row():
324
  gal_her2 = gr.Image(type="pil", label="Generated HER2", height=280)
325
  gal_ki67 = gr.Image(type="pil", label="Generated Ki67", height=280)
@@ -333,13 +334,13 @@ with gr.Blocks(title="UNIStainNet -- Virtual IHC Staining") as demo:
333
  gallery_dropdown.change(
334
  fn=_show_gallery_wrapper,
335
  inputs=[gallery_dropdown],
336
- outputs=[gal_he, gal_her2, gal_ki67, gal_er, gal_pr, gallery_info_box],
337
  )
338
 
339
  # Auto-load first example
340
  demo.load(
341
- fn=lambda: _show_gallery_wrapper(gallery_display_names[0]) if gallery_display_names else (None,) * 6,
342
- outputs=[gal_he, gal_her2, gal_ki67, gal_er, gal_pr, gallery_info_box],
343
  )
344
 
345
  # ── Tab 2: Single Stain ──────────────────────────────────────
 
244
 
245
 
246
  def show_gallery(display_name, gallery, name_map):
247
+ """Show a gallery example by its display name."""
248
  key = name_map.get(display_name)
249
  if not key or not gallery or key not in gallery:
250
+ return None, None, None, None, None, None, ""
251
  entry = gallery[key]
252
  base = GALLERY_DIR / "images"
 
253
  he = Image.open(base / entry["he"]).convert("RGB") if "he" in entry else None
254
+ gt = Image.open(base / entry["gt"]).convert("RGB") if "gt" in entry else None
255
  gen_her2 = Image.open(base / entry["gen_her2"]).convert("RGB") if "gen_her2" in entry else None
256
  gen_ki67 = Image.open(base / entry["gen_ki67"]).convert("RGB") if "gen_ki67" in entry else None
257
  gen_er = Image.open(base / entry["gen_er"]).convert("RGB") if "gen_er" in entry else None
258
  gen_pr = Image.open(base / entry["gen_pr"]).convert("RGB") if "gen_pr" in entry else None
259
 
 
260
  gt_stain = entry.get("gt_stain", "Unknown")
261
+ info = f"**Ground truth stain:** {gt_stain}"
262
+ return he, gt, gen_her2, gen_ki67, gen_er, gen_pr, info
263
 
264
 
265
  # ── Build Gradio App ─────────────────────────────────────────────────
 
306
  else:
307
  gr.Markdown(
308
  "Browse pre-computed virtual staining results -- **no GPU required**. "
309
+ "Each example shows the H&E input, ground truth IHC, and all 4 generated stains from our unified model."
310
  )
311
  gallery_dropdown = gr.Dropdown(
312
  choices=gallery_display_names,
 
315
  )
316
  gallery_info_box = gr.Markdown(value="")
317
 
318
+ gr.Markdown("### Input & Ground Truth")
319
+ with gr.Row():
320
+ gal_he = gr.Image(type="pil", label="H&E Input", height=300)
321
+ gal_gt = gr.Image(type="pil", label="Ground Truth IHC", height=300)
322
 
323
+ gr.Markdown("### Generated IHC Stains (all from the same H&E)")
324
  with gr.Row():
325
  gal_her2 = gr.Image(type="pil", label="Generated HER2", height=280)
326
  gal_ki67 = gr.Image(type="pil", label="Generated Ki67", height=280)
 
334
  gallery_dropdown.change(
335
  fn=_show_gallery_wrapper,
336
  inputs=[gallery_dropdown],
337
+ outputs=[gal_he, gal_gt, gal_her2, gal_ki67, gal_er, gal_pr, gallery_info_box],
338
  )
339
 
340
  # Auto-load first example
341
  demo.load(
342
+ fn=lambda: _show_gallery_wrapper(gallery_display_names[0]) if gallery_display_names else (None,) * 7,
343
+ outputs=[gal_he, gal_gt, gal_her2, gal_ki67, gal_er, gal_pr, gallery_info_box],
344
  )
345
 
346
  # ── Tab 2: Single Stain ──────────────────────────────────────
gallery/metadata.json CHANGED
@@ -1,84 +1,4 @@
1
  {
2
- "BCI_HER2_0_00198_test_0": {
3
- "he": "BCI_HER2_0_00198_test_0_he.png",
4
- "gt": "BCI_HER2_0_00198_test_0_gt.png",
5
- "gt_stain": "HER2",
6
- "source": "BCI",
7
- "gen_her2": "BCI_HER2_0_00198_test_0_gen_her2.png",
8
- "gen_ki67": "BCI_HER2_0_00198_test_0_gen_ki67.png",
9
- "gen_er": "BCI_HER2_0_00198_test_0_gen_er.png",
10
- "gen_pr": "BCI_HER2_0_00198_test_0_gen_pr.png"
11
- },
12
- "BCI_HER2_0_00013_test_0": {
13
- "he": "BCI_HER2_0_00013_test_0_he.png",
14
- "gt": "BCI_HER2_0_00013_test_0_gt.png",
15
- "gt_stain": "HER2",
16
- "source": "BCI",
17
- "gen_her2": "BCI_HER2_0_00013_test_0_gen_her2.png",
18
- "gen_ki67": "BCI_HER2_0_00013_test_0_gen_ki67.png",
19
- "gen_er": "BCI_HER2_0_00013_test_0_gen_er.png",
20
- "gen_pr": "BCI_HER2_0_00013_test_0_gen_pr.png"
21
- },
22
- "BCI_HER2_1+_00791_test_1+": {
23
- "he": "BCI_HER2_1+_00791_test_1+_he.png",
24
- "gt": "BCI_HER2_1+_00791_test_1+_gt.png",
25
- "gt_stain": "HER2",
26
- "source": "BCI",
27
- "gen_her2": "BCI_HER2_1+_00791_test_1+_gen_her2.png",
28
- "gen_ki67": "BCI_HER2_1+_00791_test_1+_gen_ki67.png",
29
- "gen_er": "BCI_HER2_1+_00791_test_1+_gen_er.png",
30
- "gen_pr": "BCI_HER2_1+_00791_test_1+_gen_pr.png"
31
- },
32
- "BCI_HER2_1+_00276_test_1+": {
33
- "he": "BCI_HER2_1+_00276_test_1+_he.png",
34
- "gt": "BCI_HER2_1+_00276_test_1+_gt.png",
35
- "gt_stain": "HER2",
36
- "source": "BCI",
37
- "gen_her2": "BCI_HER2_1+_00276_test_1+_gen_her2.png",
38
- "gen_ki67": "BCI_HER2_1+_00276_test_1+_gen_ki67.png",
39
- "gen_er": "BCI_HER2_1+_00276_test_1+_gen_er.png",
40
- "gen_pr": "BCI_HER2_1+_00276_test_1+_gen_pr.png"
41
- },
42
- "BCI_HER2_2+_00293_test_2+": {
43
- "he": "BCI_HER2_2+_00293_test_2+_he.png",
44
- "gt": "BCI_HER2_2+_00293_test_2+_gt.png",
45
- "gt_stain": "HER2",
46
- "source": "BCI",
47
- "gen_her2": "BCI_HER2_2+_00293_test_2+_gen_her2.png",
48
- "gen_ki67": "BCI_HER2_2+_00293_test_2+_gen_ki67.png",
49
- "gen_er": "BCI_HER2_2+_00293_test_2+_gen_er.png",
50
- "gen_pr": "BCI_HER2_2+_00293_test_2+_gen_pr.png"
51
- },
52
- "BCI_HER2_2+_00259_test_2+": {
53
- "he": "BCI_HER2_2+_00259_test_2+_he.png",
54
- "gt": "BCI_HER2_2+_00259_test_2+_gt.png",
55
- "gt_stain": "HER2",
56
- "source": "BCI",
57
- "gen_her2": "BCI_HER2_2+_00259_test_2+_gen_her2.png",
58
- "gen_ki67": "BCI_HER2_2+_00259_test_2+_gen_ki67.png",
59
- "gen_er": "BCI_HER2_2+_00259_test_2+_gen_er.png",
60
- "gen_pr": "BCI_HER2_2+_00259_test_2+_gen_pr.png"
61
- },
62
- "BCI_HER2_3+_00277_test_3+": {
63
- "he": "BCI_HER2_3+_00277_test_3+_he.png",
64
- "gt": "BCI_HER2_3+_00277_test_3+_gt.png",
65
- "gt_stain": "HER2",
66
- "source": "BCI",
67
- "gen_her2": "BCI_HER2_3+_00277_test_3+_gen_her2.png",
68
- "gen_ki67": "BCI_HER2_3+_00277_test_3+_gen_ki67.png",
69
- "gen_er": "BCI_HER2_3+_00277_test_3+_gen_er.png",
70
- "gen_pr": "BCI_HER2_3+_00277_test_3+_gen_pr.png"
71
- },
72
- "BCI_HER2_3+_00220_test_3+": {
73
- "he": "BCI_HER2_3+_00220_test_3+_he.png",
74
- "gt": "BCI_HER2_3+_00220_test_3+_gt.png",
75
- "gt_stain": "HER2",
76
- "source": "BCI",
77
- "gen_her2": "BCI_HER2_3+_00220_test_3+_gen_her2.png",
78
- "gen_ki67": "BCI_HER2_3+_00220_test_3+_gen_ki67.png",
79
- "gen_er": "BCI_HER2_3+_00220_test_3+_gen_er.png",
80
- "gen_pr": "BCI_HER2_3+_00220_test_3+_gen_pr.png"
81
- },
82
  "MIST_HER2_67M2100642_15_18": {
83
  "he": "MIST_HER2_67M2100642_15_18_he.png",
84
  "gt": "MIST_HER2_67M2100642_15_18_gt.png",
 
1
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  "MIST_HER2_67M2100642_15_18": {
3
  "he": "MIST_HER2_67M2100642_15_18_he.png",
4
  "gt": "MIST_HER2_67M2100642_15_18_gt.png",