ibrahim313 commited on
Commit
b240133
·
verified ·
1 Parent(s): 0d5b33e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +116 -28
app.py CHANGED
@@ -4,60 +4,148 @@ import numpy as np
4
  import pandas as pd
5
  from collections import Counter
6
  from ultralytics import YOLO
7
- from huggingface_hub import hf_hub_download
8
-
9
- # # Download YOLOv10 model from Hugging Face
10
- # MODEL_PATH = hf_hub_download(
11
- # repo_id="ibrahim313/Bioengineering_Query_Tool_image_based",
12
- # filename="best.pt"
13
- # )
14
 
15
  # Load the model
16
  model = YOLO("best.pt")
17
 
18
- def process_image(image):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  """Detect cells in the image, extract attributes, and return results."""
 
 
 
20
  # Convert image to RGB
21
  image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
22
 
23
  # Perform detection
24
- results = model.predict(source=image_rgb, imgsz=640, conf=0.25)
25
 
26
  # Get annotated image
27
  annotated_img = results[0].plot()
28
 
29
  # Extract detection data
30
  detections = results[0].boxes.data if results[0].boxes is not None else []
 
31
  if len(detections) > 0:
 
32
  class_names = [model.names[int(cls)] for cls in detections[:, 5]]
33
  count = Counter(class_names)
34
- detection_str = ', '.join([f"{name}: {count[name]}" for name in count])
35
 
36
- # Extract cell attributes (position, size, etc.)
37
  df = pd.DataFrame(detections.numpy(), columns=["x_min", "y_min", "x_max", "y_max", "confidence", "class"])
38
  df["class_name"] = df["class"].apply(lambda x: model.names[int(x)])
39
  df["width"] = df["x_max"] - df["x_min"]
40
  df["height"] = df["y_max"] - df["y_min"]
41
  df["area"] = df["width"] * df["height"]
42
 
43
- summary = df.groupby("class_name")["area"].describe().reset_index()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  else:
45
- detection_str = "No detections"
46
- summary = pd.DataFrame(columns=["class_name", "count", "mean", "std", "min", "25%", "50%", "75%", "max"])
47
-
48
- return annotated_img, detection_str, summary
 
 
 
49
 
50
- # Create Gradio interface
51
- app = gr.Interface(
52
- fn=process_image,
53
- inputs=gr.Image(type="numpy", label="Upload an Image"),
54
- outputs=[
55
- gr.Image(type="numpy", label="Annotated Image"),
56
- gr.Textbox(label="Detection Counts"),
57
- gr.Dataframe(label="Cell Statistics")
58
- ],
59
- title="Bioengineering Image Analysis Tool",
60
- description="Upload an image to detect and analyze bioengineering cells using YOLOv10."
61
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
 
63
  app.launch()
 
4
  import pandas as pd
5
  from collections import Counter
6
  from ultralytics import YOLO
7
+ import plotly.express as px
8
+ import plotly.graph_objects as go
 
 
 
 
 
9
 
10
  # Load the model
11
  model = YOLO("best.pt")
12
 
13
+ def create_size_distribution_plot(df):
14
+ """Create a box plot of cell sizes for each class."""
15
+ fig = px.box(df, x="class_name", y="area", title="Cell Size Distribution by Type")
16
+ fig.update_layout(
17
+ xaxis_title="Cell Type",
18
+ yaxis_title="Area (pixels²)",
19
+ template="plotly_white"
20
+ )
21
+ return fig
22
+
23
+ def create_density_heatmap(df, image_shape):
24
+ """Create a heatmap showing cell density."""
25
+ heatmap = np.zeros(image_shape[:2])
26
+ for _, row in df.iterrows():
27
+ center_x = int((row['x_min'] + row['x_max']) / 2)
28
+ center_y = int((row['y_min'] + row['y_max']) / 2)
29
+ heatmap[max(0, center_y-20):min(image_shape[0], center_y+20),
30
+ max(0, center_x-20):min(image_shape[1], center_x+20)] += 1
31
+
32
+ fig = go.Figure(data=go.Heatmap(z=heatmap))
33
+ fig.update_layout(title="Cell Density Heatmap")
34
+ return fig
35
+
36
+ def process_image(image, conf_threshold=0.25):
37
  """Detect cells in the image, extract attributes, and return results."""
38
+ if image is None:
39
+ return None, "No image uploaded", None, None, None
40
+
41
  # Convert image to RGB
42
  image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
43
 
44
  # Perform detection
45
+ results = model.predict(source=image_rgb, imgsz=640, conf=conf_threshold)
46
 
47
  # Get annotated image
48
  annotated_img = results[0].plot()
49
 
50
  # Extract detection data
51
  detections = results[0].boxes.data if results[0].boxes is not None else []
52
+
53
  if len(detections) > 0:
54
+ # Count detections
55
  class_names = [model.names[int(cls)] for cls in detections[:, 5]]
56
  count = Counter(class_names)
57
+ detection_str = '\n'.join([f"{name}: {count[name]} cells detected" for name in count])
58
 
59
+ # Create detailed DataFrame
60
  df = pd.DataFrame(detections.numpy(), columns=["x_min", "y_min", "x_max", "y_max", "confidence", "class"])
61
  df["class_name"] = df["class"].apply(lambda x: model.names[int(x)])
62
  df["width"] = df["x_max"] - df["x_min"]
63
  df["height"] = df["y_max"] - df["y_min"]
64
  df["area"] = df["width"] * df["height"]
65
 
66
+ # Generate summary statistics
67
+ summary = df.groupby("class_name").agg({
68
+ 'area': ['count', 'mean', 'std', 'min', 'max'],
69
+ 'confidence': 'mean'
70
+ }).round(2)
71
+ summary.columns = ['Count', 'Mean Area', 'Std Dev', 'Min Area', 'Max Area', 'Avg Confidence']
72
+ summary = summary.reset_index()
73
+
74
+ # Create visualizations
75
+ size_dist_plot = create_size_distribution_plot(df)
76
+ density_plot = create_density_heatmap(df, image.shape)
77
+
78
+ return (
79
+ annotated_img,
80
+ detection_str,
81
+ summary,
82
+ size_dist_plot,
83
+ density_plot
84
+ )
85
  else:
86
+ return (
87
+ annotated_img,
88
+ "No cells detected",
89
+ pd.DataFrame(),
90
+ None,
91
+ None
92
+ )
93
 
94
+ # Create Gradio interface with improved layout
95
+ with gr.Blocks(theme=gr.themes.Soft()) as app:
96
+ gr.Markdown("""
97
+ # Bioengineering Image Analysis Tool
98
+ Upload microscopy images to detect and analyze cells using YOLOv10.
99
+ """)
100
+
101
+ with gr.Row():
102
+ with gr.Column(scale=1):
103
+ input_image = gr.Image(type="numpy", label="Upload Image")
104
+ conf_slider = gr.Slider(
105
+ minimum=0.1,
106
+ maximum=1.0,
107
+ value=0.25,
108
+ step=0.05,
109
+ label="Confidence Threshold",
110
+ info="Adjust detection sensitivity"
111
+ )
112
+ analyze_btn = gr.Button("Analyze Image", variant="primary")
113
+
114
+ with gr.Column(scale=1):
115
+ output_image = gr.Image(type="numpy", label="Detected Cells")
116
+ detection_text = gr.Textbox(label="Detection Summary", lines=3)
117
+
118
+ with gr.Row():
119
+ with gr.Column(scale=1):
120
+ stats_df = gr.Dataframe(
121
+ label="Cell Statistics",
122
+ headers=['Cell Type', 'Count', 'Mean Area', 'Std Dev', 'Min Area', 'Max Area', 'Avg Confidence']
123
+ )
124
+
125
+ with gr.Row():
126
+ with gr.Column(scale=1):
127
+ size_plot = gr.Plot(label="Cell Size Distribution")
128
+ with gr.Column(scale=1):
129
+ density_plot = gr.Plot(label="Cell Density Heatmap")
130
+
131
+ # Handle button click
132
+ analyze_btn.click(
133
+ process_image,
134
+ inputs=[input_image, conf_slider],
135
+ outputs=[output_image, detection_text, stats_df, size_plot, density_plot]
136
+ )
137
+
138
+ gr.Markdown("""
139
+ ### Instructions:
140
+ 1. Upload a microscopy image containing cells
141
+ 2. Adjust the confidence threshold if needed (higher values = stricter detection)
142
+ 3. Click 'Analyze Image' to process
143
+ 4. View results in the various panels:
144
+ - Annotated image shows detected cells
145
+ - Summary provides cell counts
146
+ - Statistics table shows detailed measurements
147
+ - Plots visualize size distribution and spatial density
148
+ """)
149
 
150
+ # Launch the app
151
  app.launch()