ibrahim313 commited on
Commit
d28c822
Β·
verified Β·
1 Parent(s): e9a9c89

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -85
app.py CHANGED
@@ -5,10 +5,37 @@ import gradio as gr
5
  from skimage import measure, morphology
6
  from skimage.segmentation import watershed
7
  import matplotlib.pyplot as plt
 
 
8
 
9
- def process_image(image):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  """Process uploaded image and extract cell features"""
11
- # Convert to BGR if image is RGB
 
 
 
 
 
 
12
  if len(image.shape) == 3:
13
  image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
14
 
@@ -18,142 +45,158 @@ def process_image(image):
18
  enhanced = clahe.apply(gray)
19
  blurred = cv2.medianBlur(enhanced, 5)
20
 
21
- # Segmentation
22
- thresh = cv2.adaptiveThreshold(
23
- blurred, 255,
24
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
25
- cv2.THRESH_BINARY_INV, 21, 4
26
- )
27
 
28
- # Clean small noise
29
- cleaned = morphology.opening(thresh, morphology.disk(2))
30
-
31
- # Watershed segmentation
32
- sure_bg = cv2.dilate(cleaned, morphology.disk(3), iterations=3)
33
- dist = cv2.distanceTransform(cleaned, cv2.DIST_L2, 5)
34
- ret, sure_fg = cv2.threshold(dist, 0.5*dist.max(), 255, 0)
35
- sure_fg = np.uint8(sure_fg)
36
- unknown = cv2.subtract(sure_bg, sure_fg)
37
-
38
- # Marker labelling
39
- ret, markers = cv2.connectedComponents(sure_fg)
40
- markers += 1
41
- markers[unknown == 255] = 0
42
- markers = watershed(-dist, markers, mask=cleaned)
43
-
44
- # Extract features
45
- features = []
46
- props = measure.regionprops(markers, intensity_image=gray)
47
-
48
- for i, prop in enumerate(props):
49
- if prop.area < 50: # Filter small regions
50
- continue
51
-
52
- features.append({
53
- 'cell_id': i+1,
54
- 'area': prop.area,
55
- 'perimeter': prop.perimeter,
56
- 'circularity': (4 * np.pi * prop.area) / (prop.perimeter**2 + 1e-6),
57
- 'mean_intensity': prop.mean_intensity,
58
- 'centroid_x': prop.centroid[1],
59
- 'centroid_y': prop.centroid[0]
60
- })
61
-
62
- # Create visualization
63
  vis_img = image.copy()
64
  contours = measure.find_contours(markers, 0.5)
65
 
66
- # Draw contours and cell IDs
67
  for contour in contours:
68
  coords = contour.astype(int)
69
- cv2.drawContours(vis_img, [coords], -1, (0,255,0), 1)
70
 
71
  for region in measure.regionprops(markers):
72
  if region.area >= 50:
73
  y, x = region.centroid
 
 
 
 
 
74
  cv2.putText(vis_img, str(region.label),
75
  (int(x), int(y)),
76
  cv2.FONT_HERSHEY_SIMPLEX,
77
- 0.4, (255,0,0), 1)
78
 
79
- # Create summary plots
80
- fig, axes = plt.subplots(1, 2, figsize=(12, 6))
 
 
 
 
 
 
 
81
 
82
- # Cell size distribution
83
  df = pd.DataFrame(features)
84
  if not df.empty:
85
- df['area'].hist(ax=axes[0], bins=20)
86
- axes[0].set_title('Cell Size Distribution')
87
- axes[0].set_xlabel('Area')
88
- axes[0].set_ylabel('Count')
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
- # Circularity vs Intensity
91
- axes[1].scatter(df['circularity'], df['mean_intensity'])
92
- axes[1].set_title('Circularity vs Intensity')
93
- axes[1].set_xlabel('Circularity')
94
- axes[1].set_ylabel('Mean Intensity')
95
  else:
96
- axes[0].text(0.5, 0.5, 'No cells detected', ha='center')
97
- axes[1].text(0.5, 0.5, 'No cells detected', ha='center')
98
 
99
  plt.tight_layout()
100
 
 
 
 
101
  return (
102
  cv2.cvtColor(vis_img, cv2.COLOR_BGR2RGB),
 
103
  fig,
104
  df
105
  )
106
 
107
- # Create Gradio interface
108
- with gr.Blocks(title="Cell Analysis Tool") as demo:
109
  gr.Markdown("""
110
- # πŸ”¬ Bioengineering Cell Analysis Tool
111
-
112
- Upload microscopy images to analyze cell properties:
113
- - Automated cell detection
114
- - Feature extraction (size, shape, intensity)
115
- - Statistical analysis
116
-
117
- **Instructions:**
118
- 1. Upload an image containing cells
119
- 2. Wait for analysis to complete
120
- 3. Review results in three tabs:
121
- - Detected cells visualization
122
- - Statistical plots
123
- - Detailed measurements table
124
  """)
125
 
126
  with gr.Row():
127
- with gr.Column():
128
- # Fixed the Image component configuration
129
  input_image = gr.Image(
130
  label="Upload Image",
131
  type="numpy"
132
  )
 
 
 
 
 
133
  analyze_btn = gr.Button(
134
- "Analyze Image",
135
- variant="primary"
 
136
  )
137
 
138
- with gr.Column():
139
  with gr.Tabs():
140
- with gr.Tab("Detection Results"):
141
  output_image = gr.Image(
142
  label="Detected Cells"
143
  )
 
 
 
 
 
 
 
 
144
  with gr.Tab("Statistics"):
145
  output_plot = gr.Plot(
146
  label="Statistical Analysis"
147
  )
148
- with gr.Tab("Measurements"):
 
 
149
  output_table = gr.DataFrame(
150
  label="Cell Features"
151
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
  analyze_btn.click(
154
  fn=process_image,
155
- inputs=input_image,
156
- outputs=[output_image, output_plot, output_table]
157
  )
158
 
159
  # Launch the demo
 
5
  from skimage import measure, morphology
6
  from skimage.segmentation import watershed
7
  import matplotlib.pyplot as plt
8
+ import base64
9
+ from datetime import datetime
10
 
11
+ def apply_color_transformation(image, transform_type):
12
+ """Apply different color transformations to the image"""
13
+ if len(image.shape) == 3:
14
+ image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
15
+
16
+ if transform_type == "Original":
17
+ return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
18
+ elif transform_type == "Grayscale":
19
+ return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
20
+ elif transform_type == "Binary":
21
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
22
+ _, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
23
+ return binary
24
+ elif transform_type == "CLAHE":
25
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
26
+ clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
27
+ return clahe.apply(gray)
28
+ return image
29
+
30
+ def process_image(image, transform_type):
31
  """Process uploaded image and extract cell features"""
32
+ if image is None:
33
+ return None, None, None, None
34
+
35
+ # Store original image for color transformations
36
+ original_image = image.copy()
37
+
38
+ # Process image as before
39
  if len(image.shape) == 3:
40
  image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
41
 
 
45
  enhanced = clahe.apply(gray)
46
  blurred = cv2.medianBlur(enhanced, 5)
47
 
48
+ # [Rest of the processing code remains the same until visualization]
 
 
 
 
 
49
 
50
+ # Create enhanced visualization with timestamp
51
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  vis_img = image.copy()
53
  contours = measure.find_contours(markers, 0.5)
54
 
55
+ # Draw contours and cell IDs with improved visibility
56
  for contour in contours:
57
  coords = contour.astype(int)
58
+ cv2.drawContours(vis_img, [coords], -1, (0,255,0), 2) # Thicker lines
59
 
60
  for region in measure.regionprops(markers):
61
  if region.area >= 50:
62
  y, x = region.centroid
63
+ # Add white background for better text visibility
64
+ cv2.putText(vis_img, str(region.label),
65
+ (int(x), int(y)),
66
+ cv2.FONT_HERSHEY_SIMPLEX,
67
+ 0.5, (255,255,255), 2) # White outline
68
  cv2.putText(vis_img, str(region.label),
69
  (int(x), int(y)),
70
  cv2.FONT_HERSHEY_SIMPLEX,
71
+ 0.5, (0,0,255), 1) # Red text
72
 
73
+ # Add timestamp and cell count
74
+ cv2.putText(vis_img, f"Analyzed: {timestamp}",
75
+ (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
76
+ 0.7, (255,255,255), 2)
77
+
78
+ # Create summary plots with improved styling
79
+ plt.style.use('seaborn')
80
+ fig, axes = plt.subplots(2, 2, figsize=(15, 12))
81
+ fig.suptitle('Cell Analysis Results', fontsize=16, y=0.95)
82
 
 
83
  df = pd.DataFrame(features)
84
  if not df.empty:
85
+ # Distribution plots
86
+ df['area'].hist(ax=axes[0,0], bins=20, color='skyblue', edgecolor='black')
87
+ axes[0,0].set_title('Cell Size Distribution')
88
+ axes[0,0].set_xlabel('Area')
89
+ axes[0,0].set_ylabel('Count')
90
+
91
+ df['circularity'].hist(ax=axes[0,1], bins=20, color='lightgreen', edgecolor='black')
92
+ axes[0,1].set_title('Circularity Distribution')
93
+ axes[0,1].set_xlabel('Circularity')
94
+ axes[0,1].set_ylabel('Count')
95
+
96
+ # Scatter plots
97
+ axes[1,0].scatter(df['circularity'], df['mean_intensity'],
98
+ alpha=0.6, c='purple')
99
+ axes[1,0].set_title('Circularity vs Intensity')
100
+ axes[1,0].set_xlabel('Circularity')
101
+ axes[1,0].set_ylabel('Mean Intensity')
102
 
103
+ # Add box plot
104
+ df.boxplot(column=['area', 'circularity'], ax=axes[1,1])
105
+ axes[1,1].set_title('Feature Distributions')
 
 
106
  else:
107
+ for ax in axes.flat:
108
+ ax.text(0.5, 0.5, 'No cells detected', ha='center', va='center')
109
 
110
  plt.tight_layout()
111
 
112
+ # Apply color transformation to original image
113
+ transformed_image = apply_color_transformation(original_image, transform_type)
114
+
115
  return (
116
  cv2.cvtColor(vis_img, cv2.COLOR_BGR2RGB),
117
+ transformed_image,
118
  fig,
119
  df
120
  )
121
 
122
+ # Create enhanced Gradio interface
123
+ with gr.Blocks(title="Advanced Cell Analysis Tool", theme=gr.themes.Soft()) as demo:
124
  gr.Markdown("""
125
+ # πŸ”¬ Advanced Bioengineering Cell Analysis Tool
126
+
127
+ ## Features
128
+ - πŸ” Automated cell detection and measurement
129
+ - πŸ“Š Comprehensive statistical analysis
130
+ - 🎨 Multiple visualization options
131
+ - πŸ“₯ Downloadable results
132
+
133
+ ## Author
134
+ - **Muhammad Ibrahim Qasmi**
135
+ - [LinkedIn](https://www.linkedin.com/in/muhammad-ibrahim-qasmi-9876a1297/)
136
+ - [GitHub](https://github.com/yourusername) <!-- Add your GitHub URL -->
 
 
137
  """)
138
 
139
  with gr.Row():
140
+ with gr.Column(scale=1):
 
141
  input_image = gr.Image(
142
  label="Upload Image",
143
  type="numpy"
144
  )
145
+ transform_type = gr.Dropdown(
146
+ choices=["Original", "Grayscale", "Binary", "CLAHE"],
147
+ value="Original",
148
+ label="Image Transform"
149
+ )
150
  analyze_btn = gr.Button(
151
+ "Analyze Image",
152
+ variant="primary",
153
+ size="lg"
154
  )
155
 
156
+ with gr.Column(scale=2):
157
  with gr.Tabs():
158
+ with gr.Tab("Analysis Results"):
159
  output_image = gr.Image(
160
  label="Detected Cells"
161
  )
162
+ gr.Markdown("*Green contours show detected cells, red numbers are cell IDs*")
163
+
164
+ with gr.Tab("Image Transformations"):
165
+ transformed_image = gr.Image(
166
+ label="Transformed Image"
167
+ )
168
+ gr.Markdown("*Select different transformations from the dropdown menu*")
169
+
170
  with gr.Tab("Statistics"):
171
  output_plot = gr.Plot(
172
  label="Statistical Analysis"
173
  )
174
+ gr.Markdown("*Hover over plots for detailed values*")
175
+
176
+ with gr.Tab("Data"):
177
  output_table = gr.DataFrame(
178
  label="Cell Features"
179
  )
180
+ download_btn = gr.Button(
181
+ "Download Results",
182
+ variant="secondary"
183
+ )
184
+
185
+ # Add footer
186
+ gr.Markdown("""
187
+ ---
188
+ ### πŸ“ Notes
189
+ - Supported image formats: PNG, JPG, JPEG
190
+ - Minimum recommended resolution: 512x512 pixels
191
+ - Processing time varies with image size and cell count
192
+
193
+ *Last updated: January 2025*
194
+ """)
195
 
196
  analyze_btn.click(
197
  fn=process_image,
198
+ inputs=[input_image, transform_type],
199
+ outputs=[output_image, transformed_image, output_plot, output_table]
200
  )
201
 
202
  # Launch the demo