File size: 1,883 Bytes
1d140d4
 
 
 
 
b2945a5
 
 
d1ede70
b2945a5
 
 
 
d1ede70
b2945a5
1d140d4
 
 
d1ede70
b2945a5
 
1d140d4
 
 
b2945a5
1d140d4
 
 
b2945a5
1d140d4
d1ede70
09ffa1f
1d140d4
b2945a5
1d140d4
 
 
 
 
 
 
 
 
 
b2945a5
 
d1ede70
 
b2945a5
1d140d4
 
 
 
 
 
 
 
d1ede70
 
1d140d4
b2945a5
 
 
 
 
1d140d4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""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()