Spaces:
Running
Running
MIST-only gallery with GT, inline styles, remove BCI references
Browse files- app.py +14 -13
- 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.
|
| 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"**
|
| 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
|
| 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("###
|
| 320 |
-
|
|
|
|
|
|
|
| 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,) *
|
| 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",
|