Spaces:
Sleeping
Sleeping
| """Gradio app: detect cells in a fluorescence image. | |
| Upload an RGB image (blue = nuclei, red = cytoplasm), click Analyze, | |
| get one grayscale output per detected cell with cell + nucleus boundaries | |
| drawn in yellow. | |
| """ | |
| from __future__ import annotations | |
| import cv2 | |
| import gradio as gr | |
| import numpy as np | |
| from PIL import Image | |
| from quantification import analyze_image | |
| N_CELLS = 5 | |
| DILATION_RADIUS = 12 | |
| OUTLINE_COLOR_RGB = (255, 255, 0) | |
| OUTLINE_THICKNESS = 2 | |
| def analyze(image_path: str | None) -> list[np.ndarray]: | |
| if image_path is None: | |
| return [] | |
| arr = np.array(Image.open(image_path).convert("RGB")) | |
| if arr.dtype != np.uint8: | |
| arr = np.clip(arr, 0, 255).astype(np.uint8) | |
| red = arr[..., 0] | |
| gray_rgb = np.stack([red, red, red], axis=-1) | |
| cells = analyze_image(arr, n_cells=N_CELLS, dilation_radius=DILATION_RADIUS) | |
| outputs: list[np.ndarray] = [] | |
| for c in cells: | |
| canvas = gray_rgb.copy() | |
| for mask in (c.cell_mask, c.nucleus_mask): | |
| contours, _ = cv2.findContours( | |
| mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE | |
| ) | |
| cv2.drawContours(canvas, contours, -1, OUTLINE_COLOR_RGB, OUTLINE_THICKNESS) | |
| outputs.append(canvas) | |
| return outputs | |
| def build_demo() -> gr.Blocks: | |
| with gr.Blocks(title="Cell Boundary Detection") as demo: | |
| with gr.Row(): | |
| with gr.Column(): | |
| image_in = gr.Image(label="Upload image", type="filepath") | |
| run_btn = gr.Button("Analyze", variant="primary") | |
| gallery = gr.Gallery( | |
| label="Detected cells", | |
| columns=2, | |
| height=620, | |
| object_fit="contain", | |
| ) | |
| run_btn.click(analyze, inputs=image_in, outputs=gallery) | |
| return demo | |
| if __name__ == "__main__": | |
| build_demo().launch() |