ibrahim313's picture
Update app.py
e5fea54 verified
raw
history blame
5.68 kB
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
import os
# 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
)
def load_example_image():
"""Load the example test image"""
example_image = cv2.imread("test.png")
if example_image is None:
return None
return example_image
# 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")
with gr.Row():
example_btn = gr.Button("Try Example Image")
analyze_btn = gr.Button("Analyze Image", variant="primary")
conf_slider = gr.Slider(
minimum=0.1,
maximum=1.0,
value=0.25,
step=0.05,
label="Confidence Threshold",
info="Adjust detection sensitivity"
)
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 clicks
example_btn.click(
load_example_image,
outputs=input_image
)
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 or click 'Try Example Image'
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()