File size: 5,274 Bytes
f765816 8312ddd 0d5b33e f765816 b240133 7702060 0d5b33e f765816 b240133 0d5b33e b240133 0d5b33e f765816 0d5b33e b240133 f765816 0d5b33e f765816 b240133 0d5b33e b240133 0d5b33e b240133 0d5b33e b240133 0d5b33e b240133 0d5b33e b240133 f765816 b240133 1cd6596 b240133 0d5b33e |
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
import gradio as gr
import cv2
import numpy as np
import pandas as pd
from collections import Counter
from ultralytics import YOLO
import plotly.express as px
import plotly.graph_objects as go
# Load the model
model = YOLO("best.pt")
def create_size_distribution_plot(df):
"""Create a box plot of cell sizes for each class."""
fig = px.box(df, x="class_name", y="area", title="Cell Size Distribution by Type")
fig.update_layout(
xaxis_title="Cell Type",
yaxis_title="Area (pixels²)",
template="plotly_white"
)
return fig
def create_density_heatmap(df, image_shape):
"""Create a heatmap showing cell density."""
heatmap = np.zeros(image_shape[:2])
for _, row in df.iterrows():
center_x = int((row['x_min'] + row['x_max']) / 2)
center_y = int((row['y_min'] + row['y_max']) / 2)
heatmap[max(0, center_y-20):min(image_shape[0], center_y+20),
max(0, center_x-20):min(image_shape[1], center_x+20)] += 1
fig = go.Figure(data=go.Heatmap(z=heatmap))
fig.update_layout(title="Cell Density Heatmap")
return fig
def process_image(image, conf_threshold=0.25):
"""Detect cells in the image, extract attributes, and return results."""
if image is None:
return None, "No image uploaded", None, None, None
# Convert image to RGB
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# Perform detection
results = model.predict(source=image_rgb, imgsz=640, conf=conf_threshold)
# Get annotated image
annotated_img = results[0].plot()
# Extract detection data
detections = results[0].boxes.data if results[0].boxes is not None else []
if len(detections) > 0:
# Count detections
class_names = [model.names[int(cls)] for cls in detections[:, 5]]
count = Counter(class_names)
detection_str = '\n'.join([f"{name}: {count[name]} cells detected" for name in count])
# Create detailed DataFrame
df = pd.DataFrame(detections.numpy(), columns=["x_min", "y_min", "x_max", "y_max", "confidence", "class"])
df["class_name"] = df["class"].apply(lambda x: model.names[int(x)])
df["width"] = df["x_max"] - df["x_min"]
df["height"] = df["y_max"] - df["y_min"]
df["area"] = df["width"] * df["height"]
# Generate summary statistics
summary = df.groupby("class_name").agg({
'area': ['count', 'mean', 'std', 'min', 'max'],
'confidence': 'mean'
}).round(2)
summary.columns = ['Count', 'Mean Area', 'Std Dev', 'Min Area', 'Max Area', 'Avg Confidence']
summary = summary.reset_index()
# Create visualizations
size_dist_plot = create_size_distribution_plot(df)
density_plot = create_density_heatmap(df, image.shape)
return (
annotated_img,
detection_str,
summary,
size_dist_plot,
density_plot
)
else:
return (
annotated_img,
"No cells detected",
pd.DataFrame(),
None,
None
)
# Create Gradio interface with improved layout
with gr.Blocks(theme=gr.themes.Soft()) as app:
gr.Markdown("""
# Bioengineering Image Analysis Tool
Upload microscopy images to detect and analyze cells using YOLOv10.
""")
with gr.Row():
with gr.Column(scale=1):
input_image = gr.Image(type="numpy", label="Upload Image")
conf_slider = gr.Slider(
minimum=0.1,
maximum=1.0,
value=0.25,
step=0.05,
label="Confidence Threshold",
info="Adjust detection sensitivity"
)
analyze_btn = gr.Button("Analyze Image", variant="primary")
with gr.Column(scale=1):
output_image = gr.Image(type="numpy", label="Detected Cells")
detection_text = gr.Textbox(label="Detection Summary", lines=3)
with gr.Row():
with gr.Column(scale=1):
stats_df = gr.Dataframe(
label="Cell Statistics",
headers=['Cell Type', 'Count', 'Mean Area', 'Std Dev', 'Min Area', 'Max Area', 'Avg Confidence']
)
with gr.Row():
with gr.Column(scale=1):
size_plot = gr.Plot(label="Cell Size Distribution")
with gr.Column(scale=1):
density_plot = gr.Plot(label="Cell Density Heatmap")
# Handle button click
analyze_btn.click(
process_image,
inputs=[input_image, conf_slider],
outputs=[output_image, detection_text, stats_df, size_plot, density_plot]
)
gr.Markdown("""
### Instructions:
1. Upload a microscopy image containing cells
2. Adjust the confidence threshold if needed (higher values = stricter detection)
3. Click 'Analyze Image' to process
4. View results in the various panels:
- Annotated image shows detected cells
- Summary provides cell counts
- Statistics table shows detailed measurements
- Plots visualize size distribution and spatial density
""")
# Launch the app
app.launch() |