Spaces:
Running on Zero
Running on Zero
Commit Β·
5fb70b0
1
Parent(s): 41bd81d
update
Browse files
app.py
CHANGED
|
@@ -200,7 +200,7 @@ def colorize_mask(mask: np.ndarray, num_colors: int = 512) -> np.ndarray:
|
|
| 200 |
return palette_arr[color_idx]
|
| 201 |
|
| 202 |
# @spaces.GPU
|
| 203 |
-
def segment_with_choice(use_box_choice, annot_value):
|
| 204 |
"""Segmentation handler - supports bounding box, returns colorized overlay and original mask path"""
|
| 205 |
if annot_value is None or len(annot_value) < 1:
|
| 206 |
print("β No annotation input")
|
|
@@ -257,7 +257,7 @@ def segment_with_choice(use_box_choice, annot_value):
|
|
| 257 |
return Image.new("RGB", mask.shape[::-1], (255, 0, 0)), None
|
| 258 |
|
| 259 |
overlay = img_np.copy()
|
| 260 |
-
alpha = 0.
|
| 261 |
|
| 262 |
for inst_id in np.unique(inst_mask):
|
| 263 |
if inst_id == 0:
|
|
@@ -279,7 +279,7 @@ def segment_with_choice(use_box_choice, annot_value):
|
|
| 279 |
|
| 280 |
|
| 281 |
# @spaces.GPU
|
| 282 |
-
def count_cells_handler(use_box_choice, annot_value):
|
| 283 |
"""Counting handler - supports bounding box, returns only density map"""
|
| 284 |
if annot_value is None or len(annot_value) < 1:
|
| 285 |
return None, "β οΈ Please provide an image."
|
|
@@ -339,7 +339,7 @@ def count_cells_handler(use_box_choice, annot_value):
|
|
| 339 |
density_normalized = (density_normalized - density_normalized.min()) / (density_normalized.max() - density_normalized.min())
|
| 340 |
|
| 341 |
cmap = cm.get_cmap("jet")
|
| 342 |
-
alpha = 0.
|
| 343 |
density_colored = cmap(density_normalized)[:, :, :3] # RGB only, ignore alpha
|
| 344 |
|
| 345 |
overlay = img_np.copy()
|
|
@@ -357,7 +357,7 @@ def count_cells_handler(use_box_choice, annot_value):
|
|
| 357 |
|
| 358 |
|
| 359 |
result_text = f"β
Detected {round(count)} objects"
|
| 360 |
-
if use_box_choice == "Yes" and
|
| 361 |
result_text += f"\nπ¦ Using bounding box: {box_array}"
|
| 362 |
|
| 363 |
|
|
@@ -496,7 +496,7 @@ def extract_first_frame(tif_dir):
|
|
| 496 |
return valid_tif_files[0]
|
| 497 |
return None
|
| 498 |
|
| 499 |
-
def create_tracking_visualization(tif_dir, output_dir, valid_tif_files):
|
| 500 |
"""
|
| 501 |
Create an animated GIF/video showing tracked objects with consistent colors
|
| 502 |
|
|
@@ -534,7 +534,7 @@ def create_tracking_visualization(tif_dir, output_dir, valid_tif_files):
|
|
| 534 |
|
| 535 |
|
| 536 |
frames = []
|
| 537 |
-
alpha = 0.
|
| 538 |
|
| 539 |
# Process each frame
|
| 540 |
num_frames = min(len(valid_tif_files), len(mask_files))
|
|
@@ -664,7 +664,7 @@ def create_tracking_visualization(tif_dir, output_dir, valid_tif_files):
|
|
| 664 |
return valid_tif_files[0]
|
| 665 |
|
| 666 |
# @spaces.GPU
|
| 667 |
-
def track_video_handler(use_box_choice, first_frame_annot, zip_file_obj):
|
| 668 |
"""
|
| 669 |
Tracking handler - processes a ZIP of TIF frames, supports bounding box, returns visualization and results ZIP
|
| 670 |
|
|
@@ -765,7 +765,8 @@ def track_video_handler(use_box_choice, first_frame_annot, zip_file_obj):
|
|
| 765 |
tracking_video = create_tracking_visualization(
|
| 766 |
tif_dir,
|
| 767 |
output_temp_dir,
|
| 768 |
-
valid_tif_files
|
|
|
|
| 769 |
)
|
| 770 |
except Exception as e:
|
| 771 |
print(f"β οΈ Failed to create visualization: {e}")
|
|
@@ -799,7 +800,7 @@ def track_video_handler(use_box_choice, first_frame_annot, zip_file_obj):
|
|
| 799 |
- README.txt (Results description)
|
| 800 |
"""
|
| 801 |
|
| 802 |
-
if use_box_choice == "Yes" and
|
| 803 |
result_text += f"\nπ¦ Using bounding box: {box_array}"
|
| 804 |
|
| 805 |
print(f"\nβ
Tracking completed")
|
|
@@ -930,6 +931,13 @@ with gr.Blocks(
|
|
| 930 |
value="No",
|
| 931 |
label="π² Specify Bounding Box?"
|
| 932 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 933 |
with gr.Row():
|
| 934 |
run_seg_btn = gr.Button("βΆοΈ Run Segmentation", variant="primary", size="lg")
|
| 935 |
clear_btn = gr.Button("π Clear Selection", variant="secondary")
|
|
@@ -983,7 +991,7 @@ with gr.Blocks(
|
|
| 983 |
# click event for segmentation
|
| 984 |
run_seg_btn.click(
|
| 985 |
fn=segment_with_choice,
|
| 986 |
-
inputs=[use_box_radio, annotator],
|
| 987 |
outputs=[seg_output, download_mask_btn]
|
| 988 |
)
|
| 989 |
|
|
@@ -1105,7 +1113,14 @@ with gr.Blocks(
|
|
| 1105 |
value="No",
|
| 1106 |
label="π² Specify Bounding Box?"
|
| 1107 |
)
|
| 1108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1109 |
with gr.Row():
|
| 1110 |
count_btn = gr.Button("βΆοΈ Run Counting", variant="primary", size="lg")
|
| 1111 |
clear_btn = gr.Button("π Clear Selection", variant="secondary")
|
|
@@ -1204,7 +1219,7 @@ with gr.Blocks(
|
|
| 1204 |
# Run counting
|
| 1205 |
count_btn.click(
|
| 1206 |
fn=count_cells_handler,
|
| 1207 |
-
inputs=[count_use_box_radio, count_annotator],
|
| 1208 |
outputs=[count_output, download_density_btn, count_status]
|
| 1209 |
)
|
| 1210 |
|
|
@@ -1292,7 +1307,14 @@ with gr.Blocks(
|
|
| 1292 |
value="No",
|
| 1293 |
label="π² Specify Bounding Box?"
|
| 1294 |
)
|
| 1295 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1296 |
with gr.Row():
|
| 1297 |
track_btn = gr.Button("βΆοΈ Run Tracking", variant="primary", size="lg")
|
| 1298 |
clear_btn = gr.Button("π Clear Selection", variant="secondary")
|
|
@@ -1526,7 +1548,7 @@ with gr.Blocks(
|
|
| 1526 |
# Run tracking
|
| 1527 |
track_btn.click(
|
| 1528 |
fn=track_video_handler,
|
| 1529 |
-
inputs=[track_use_box_radio, track_first_frame_annotator, track_zip_upload],
|
| 1530 |
outputs=[track_download, track_output, track_download, track_first_frame_preview]
|
| 1531 |
)
|
| 1532 |
|
|
@@ -1571,14 +1593,16 @@ with gr.Blocks(
|
|
| 1571 |
gr.Markdown(
|
| 1572 |
"""
|
| 1573 |
---
|
| 1574 |
-
### π‘ Technical Details
|
| 1575 |
-
|
| 1576 |
-
**MicroscopyMatching** - A general-purpose microscopy image analysis toolkit based on Stable Diffusion
|
| 1577 |
-
|
| 1578 |
### π Note:
|
| 1579 |
|
| 1580 |
This project is currently available with usage limits for research trial use and feedback collection. We plan to release a free public version in the future. We are actively improving the toolkit and greatly appreciate your feedback!
|
| 1581 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1582 |
"""
|
| 1583 |
)
|
| 1584 |
|
|
|
|
| 200 |
return palette_arr[color_idx]
|
| 201 |
|
| 202 |
# @spaces.GPU
|
| 203 |
+
def segment_with_choice(use_box_choice, annot_value, overlay_alpha):
|
| 204 |
"""Segmentation handler - supports bounding box, returns colorized overlay and original mask path"""
|
| 205 |
if annot_value is None or len(annot_value) < 1:
|
| 206 |
print("β No annotation input")
|
|
|
|
| 257 |
return Image.new("RGB", mask.shape[::-1], (255, 0, 0)), None
|
| 258 |
|
| 259 |
overlay = img_np.copy()
|
| 260 |
+
alpha = float(np.clip(overlay_alpha, 0.0, 1.0))
|
| 261 |
|
| 262 |
for inst_id in np.unique(inst_mask):
|
| 263 |
if inst_id == 0:
|
|
|
|
| 279 |
|
| 280 |
|
| 281 |
# @spaces.GPU
|
| 282 |
+
def count_cells_handler(use_box_choice, annot_value, overlay_alpha):
|
| 283 |
"""Counting handler - supports bounding box, returns only density map"""
|
| 284 |
if annot_value is None or len(annot_value) < 1:
|
| 285 |
return None, "β οΈ Please provide an image."
|
|
|
|
| 339 |
density_normalized = (density_normalized - density_normalized.min()) / (density_normalized.max() - density_normalized.min())
|
| 340 |
|
| 341 |
cmap = cm.get_cmap("jet")
|
| 342 |
+
alpha = float(np.clip(overlay_alpha, 0.0, 1.0))
|
| 343 |
density_colored = cmap(density_normalized)[:, :, :3] # RGB only, ignore alpha
|
| 344 |
|
| 345 |
overlay = img_np.copy()
|
|
|
|
| 357 |
|
| 358 |
|
| 359 |
result_text = f"β
Detected {round(count)} objects"
|
| 360 |
+
if use_box_choice == "Yes" and box_array:
|
| 361 |
result_text += f"\nπ¦ Using bounding box: {box_array}"
|
| 362 |
|
| 363 |
|
|
|
|
| 496 |
return valid_tif_files[0]
|
| 497 |
return None
|
| 498 |
|
| 499 |
+
def create_tracking_visualization(tif_dir, output_dir, valid_tif_files, overlay_alpha=0.3):
|
| 500 |
"""
|
| 501 |
Create an animated GIF/video showing tracked objects with consistent colors
|
| 502 |
|
|
|
|
| 534 |
|
| 535 |
|
| 536 |
frames = []
|
| 537 |
+
alpha = float(np.clip(overlay_alpha, 0.0, 1.0)) # Transparency for overlay
|
| 538 |
|
| 539 |
# Process each frame
|
| 540 |
num_frames = min(len(valid_tif_files), len(mask_files))
|
|
|
|
| 664 |
return valid_tif_files[0]
|
| 665 |
|
| 666 |
# @spaces.GPU
|
| 667 |
+
def track_video_handler(use_box_choice, first_frame_annot, zip_file_obj, overlay_alpha):
|
| 668 |
"""
|
| 669 |
Tracking handler - processes a ZIP of TIF frames, supports bounding box, returns visualization and results ZIP
|
| 670 |
|
|
|
|
| 765 |
tracking_video = create_tracking_visualization(
|
| 766 |
tif_dir,
|
| 767 |
output_temp_dir,
|
| 768 |
+
valid_tif_files,
|
| 769 |
+
overlay_alpha=overlay_alpha
|
| 770 |
)
|
| 771 |
except Exception as e:
|
| 772 |
print(f"β οΈ Failed to create visualization: {e}")
|
|
|
|
| 800 |
- README.txt (Results description)
|
| 801 |
"""
|
| 802 |
|
| 803 |
+
if use_box_choice == "Yes" and box_array:
|
| 804 |
result_text += f"\nπ¦ Using bounding box: {box_array}"
|
| 805 |
|
| 806 |
print(f"\nβ
Tracking completed")
|
|
|
|
| 931 |
value="No",
|
| 932 |
label="π² Specify Bounding Box?"
|
| 933 |
)
|
| 934 |
+
seg_alpha_slider = gr.Slider(
|
| 935 |
+
minimum=0.0,
|
| 936 |
+
maximum=1.0,
|
| 937 |
+
step=0.05,
|
| 938 |
+
value=0.5,
|
| 939 |
+
label="ποΈ Overlay Opacity"
|
| 940 |
+
)
|
| 941 |
with gr.Row():
|
| 942 |
run_seg_btn = gr.Button("βΆοΈ Run Segmentation", variant="primary", size="lg")
|
| 943 |
clear_btn = gr.Button("π Clear Selection", variant="secondary")
|
|
|
|
| 991 |
# click event for segmentation
|
| 992 |
run_seg_btn.click(
|
| 993 |
fn=segment_with_choice,
|
| 994 |
+
inputs=[use_box_radio, annotator, seg_alpha_slider],
|
| 995 |
outputs=[seg_output, download_mask_btn]
|
| 996 |
)
|
| 997 |
|
|
|
|
| 1113 |
value="No",
|
| 1114 |
label="π² Specify Bounding Box?"
|
| 1115 |
)
|
| 1116 |
+
count_alpha_slider = gr.Slider(
|
| 1117 |
+
minimum=0.0,
|
| 1118 |
+
maximum=1.0,
|
| 1119 |
+
step=0.05,
|
| 1120 |
+
value=0.3,
|
| 1121 |
+
label="ποΈ Heatmap Opacity"
|
| 1122 |
+
)
|
| 1123 |
+
|
| 1124 |
with gr.Row():
|
| 1125 |
count_btn = gr.Button("βΆοΈ Run Counting", variant="primary", size="lg")
|
| 1126 |
clear_btn = gr.Button("π Clear Selection", variant="secondary")
|
|
|
|
| 1219 |
# Run counting
|
| 1220 |
count_btn.click(
|
| 1221 |
fn=count_cells_handler,
|
| 1222 |
+
inputs=[count_use_box_radio, count_annotator, count_alpha_slider],
|
| 1223 |
outputs=[count_output, download_density_btn, count_status]
|
| 1224 |
)
|
| 1225 |
|
|
|
|
| 1307 |
value="No",
|
| 1308 |
label="π² Specify Bounding Box?"
|
| 1309 |
)
|
| 1310 |
+
track_alpha_slider = gr.Slider(
|
| 1311 |
+
minimum=0.0,
|
| 1312 |
+
maximum=1.0,
|
| 1313 |
+
step=0.05,
|
| 1314 |
+
value=0.3,
|
| 1315 |
+
label="ποΈ Overlay Opacity"
|
| 1316 |
+
)
|
| 1317 |
+
|
| 1318 |
with gr.Row():
|
| 1319 |
track_btn = gr.Button("βΆοΈ Run Tracking", variant="primary", size="lg")
|
| 1320 |
clear_btn = gr.Button("π Clear Selection", variant="secondary")
|
|
|
|
| 1548 |
# Run tracking
|
| 1549 |
track_btn.click(
|
| 1550 |
fn=track_video_handler,
|
| 1551 |
+
inputs=[track_use_box_radio, track_first_frame_annotator, track_zip_upload, track_alpha_slider],
|
| 1552 |
outputs=[track_download, track_output, track_download, track_first_frame_preview]
|
| 1553 |
)
|
| 1554 |
|
|
|
|
| 1593 |
gr.Markdown(
|
| 1594 |
"""
|
| 1595 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1596 |
### π Note:
|
| 1597 |
|
| 1598 |
This project is currently available with usage limits for research trial use and feedback collection. We plan to release a free public version in the future. We are actively improving the toolkit and greatly appreciate your feedback!
|
| 1599 |
|
| 1600 |
+
|
| 1601 |
+
|
| 1602 |
+
### π‘ Technical Details
|
| 1603 |
+
|
| 1604 |
+
**MicroscopyMatching** - A general-purpose microscopy image analysis toolkit based on Stable Diffusion
|
| 1605 |
+
|
| 1606 |
"""
|
| 1607 |
)
|
| 1608 |
|