ibrahim313 commited on
Commit
3cf3c0d
·
verified ·
1 Parent(s): 8f2167b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -83
app.py CHANGED
@@ -3,130 +3,132 @@ import numpy as np
3
  import pandas as pd
4
  import gradio as gr
5
  from skimage import measure, morphology
6
- from skimage.segmentation import watershed
7
  import matplotlib.pyplot as plt
8
  from datetime import datetime
9
- import logging
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
  try:
36
- # Store original image for color transformations
37
  original_image = image.copy()
38
 
39
- # Convert to BGR if needed
40
- if len(image.shape) == 3:
41
- image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
42
-
43
- # Basic preprocessing
44
- gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
45
- clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
46
- enhanced = clahe.apply(gray)
47
- blurred = cv2.medianBlur(enhanced, 5)
48
-
49
- # Thresholding
50
- _, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
51
-
52
- # Noise removal and cell separation
53
- kernel = np.ones((3,3), np.uint8)
54
- opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=2)
55
-
56
- # Sure background area
57
- sure_bg = cv2.dilate(opening, kernel, iterations=3)
58
-
59
- # Finding sure foreground area
60
- dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
61
- _, sure_fg = cv2.threshold(dist_transform, 0.5 * dist_transform.max(), 255, 0)
62
- sure_fg = sure_fg.astype(np.uint8)
63
-
64
- # Finding unknown region
65
- unknown = cv2.subtract(sure_bg, sure_fg)
66
-
67
- # Marker labelling
68
- _, markers = cv2.connectedComponents(sure_fg)
69
- markers = markers + 1
70
- markers[unknown == 255] = 0
71
-
72
- # Apply watershed
73
- markers = cv2.watershed(image, markers)
74
 
75
  # Extract features
76
  features = []
77
- for region in measure.regionprops(markers):
78
- if region.area >= 50: # Filter small regions
79
- features.append({
80
- 'label': region.label,
81
- 'area': region.area,
82
- 'perimeter': region.perimeter,
83
- 'circularity': (4 * np.pi * region.area) / (region.perimeter ** 2) if region.perimeter > 0 else 0,
84
- 'mean_intensity': region.mean_intensity,
85
- 'centroid_x': region.centroid[1],
86
- 'centroid_y': region.centroid[0]
87
- })
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  # Create visualization
90
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
91
  vis_img = image.copy()
 
92
 
93
- # Draw contours
94
- contours = measure.find_contours(markers, 0.5)
95
- for contour in contours:
96
- coords = np.array(contour).astype(int)
97
- coords = coords[:, [1, 0]] # Swap x and y coordinates
98
- coords = coords.reshape((-1, 1, 2))
99
- cv2.polylines(vis_img, [coords], True, (0, 255, 0), 2)
100
-
101
- # Add cell labels and measurements
102
  for feature in features:
103
- x = int(feature['centroid_x'])
104
- y = int(feature['centroid_y'])
 
 
 
 
105
  # White outline
106
  cv2.putText(vis_img, str(feature['label']),
107
  (x, y), cv2.FONT_HERSHEY_SIMPLEX,
108
- 0.5, (255,255,255), 2)
109
  # Red text
110
  cv2.putText(vis_img, str(feature['label']),
111
  (x, y), cv2.FONT_HERSHEY_SIMPLEX,
112
- 0.5, (0,0,255), 1)
113
 
114
- # Add timestamp
115
- cv2.putText(vis_img, f"Analyzed: {timestamp}",
116
  (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
117
- 0.7, (255,255,255), 2)
118
 
119
- # Create plots
120
  plt.style.use('seaborn')
121
  fig, axes = plt.subplots(2, 2, figsize=(15, 12))
122
- fig.suptitle('Cell Analysis Results', fontsize=16, y=0.95)
123
 
124
  df = pd.DataFrame(features)
125
  if not df.empty:
126
  # Distribution plots
127
  df['area'].hist(ax=axes[0,0], bins=20, color='skyblue', edgecolor='black')
128
  axes[0,0].set_title('Cell Size Distribution')
129
- axes[0,0].set_xlabel('Area')
130
  axes[0,0].set_ylabel('Count')
131
 
132
  df['circularity'].hist(ax=axes[0,1], bins=20, color='lightgreen', edgecolor='black')
@@ -134,12 +136,11 @@ def process_image(image, transform_type):
134
  axes[0,1].set_xlabel('Circularity')
135
  axes[0,1].set_ylabel('Count')
136
 
137
- # Scatter plots
138
- axes[1,0].scatter(df['circularity'], df['mean_intensity'],
139
- alpha=0.6, c='purple')
140
- axes[1,0].set_title('Circularity vs Intensity')
141
- axes[1,0].set_xlabel('Circularity')
142
- axes[1,0].set_ylabel('Mean Intensity')
143
 
144
  # Box plot
145
  df.boxplot(column=['area', 'circularity'], ax=axes[1,1])
@@ -154,7 +155,7 @@ def process_image(image, transform_type):
154
  transformed_image = apply_color_transformation(original_image, transform_type)
155
 
156
  return (
157
- cv2.cvtColor(vis_img, cv2.COLOR_BGR2RGB),
158
  transformed_image,
159
  fig,
160
  df
@@ -164,6 +165,8 @@ def process_image(image, transform_type):
164
  print(f"Error processing image: {str(e)}")
165
  return None, None, None, None
166
 
 
 
167
  # Create Gradio interface
168
  with gr.Blocks(title="Advanced Cell Analysis Tool", theme=gr.themes.Soft()) as demo:
169
  gr.Markdown("""
 
3
  import pandas as pd
4
  import gradio as gr
5
  from skimage import measure, morphology
 
6
  import matplotlib.pyplot as plt
7
  from datetime import datetime
8
+
9
+ def detect_blood_cells(image):
10
+ """Specialized function for blood cell detection"""
11
+ # Convert to RGB if grayscale
12
+ if len(image.shape) == 2:
13
+ image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
14
+
15
+ # Convert to HSV color space
16
+ hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
17
+
18
+ # Create mask for red blood cells
19
+ # Red color has two ranges in HSV
20
+ lower_red1 = np.array([0, 70, 50])
21
+ upper_red1 = np.array([10, 255, 255])
22
+ lower_red2 = np.array([170, 70, 50])
23
+ upper_red2 = np.array([180, 255, 255])
24
+
25
+ mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
26
+ mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
27
+ mask = mask1 + mask2
28
+
29
+ # Noise removal and smoothing
30
+ kernel = np.ones((3,3), np.uint8)
31
+ mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=2)
32
+ mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=2)
33
+
34
+ # Find contours
35
+ contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
36
+
37
+ return contours, mask
38
 
39
  def apply_color_transformation(image, transform_type):
40
  """Apply different color transformations to the image"""
41
+ if len(image.shape) == 2:
42
+ image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
43
 
44
  if transform_type == "Original":
45
+ return image
46
  elif transform_type == "Grayscale":
47
+ return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
48
  elif transform_type == "Binary":
49
+ gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
50
  _, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
51
  return binary
52
  elif transform_type == "CLAHE":
53
+ gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
54
  clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
55
  return clahe.apply(gray)
56
  return image
57
 
58
  def process_image(image, transform_type):
59
+ """Process uploaded image and extract blood cell features"""
60
  if image is None:
61
  return None, None, None, None
62
 
63
  try:
64
+ # Store original image for transformations
65
  original_image = image.copy()
66
 
67
+ # Detect blood cells
68
+ contours, mask = detect_blood_cells(image)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  # Extract features
71
  features = []
72
+ for i, contour in enumerate(contours, 1):
73
+ area = cv2.contourArea(contour)
74
+ # Filter out very small or very large regions
75
+ if 100 < area < 5000: # Adjust these thresholds based on your images
76
+ perimeter = cv2.arcLength(contour, True)
77
+ circularity = 4 * np.pi * area / (perimeter * perimeter) if perimeter > 0 else 0
78
+
79
+ # Only include if it's reasonably circular
80
+ if circularity > 0.7: # Adjust threshold as needed
81
+ M = cv2.moments(contour)
82
+ if M["m00"] != 0:
83
+ cx = int(M["m10"] / M["m00"])
84
+ cy = int(M["m01"] / M["m00"])
85
+
86
+ features.append({
87
+ 'label': i,
88
+ 'area': area,
89
+ 'perimeter': perimeter,
90
+ 'circularity': circularity,
91
+ 'centroid_x': cx,
92
+ 'centroid_y': cy
93
+ })
94
 
95
  # Create visualization
 
96
  vis_img = image.copy()
97
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
98
 
99
+ # Draw contours and labels
 
 
 
 
 
 
 
 
100
  for feature in features:
101
+ contour = contours[feature['label']-1]
102
+ cv2.drawContours(vis_img, [contour], -1, (0, 255, 0), 2)
103
+
104
+ # Add cell labels
105
+ x = feature['centroid_x']
106
+ y = feature['centroid_y']
107
  # White outline
108
  cv2.putText(vis_img, str(feature['label']),
109
  (x, y), cv2.FONT_HERSHEY_SIMPLEX,
110
+ 0.5, (255, 255, 255), 2)
111
  # Red text
112
  cv2.putText(vis_img, str(feature['label']),
113
  (x, y), cv2.FONT_HERSHEY_SIMPLEX,
114
+ 0.5, (0, 0, 255), 1)
115
 
116
+ # Add timestamp and cell count
117
+ cv2.putText(vis_img, f"Analyzed: {timestamp} | Cells: {len(features)}",
118
  (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
119
+ 0.7, (255, 255, 255), 2)
120
 
121
+ # Create analysis plots
122
  plt.style.use('seaborn')
123
  fig, axes = plt.subplots(2, 2, figsize=(15, 12))
124
+ fig.suptitle('Blood Cell Analysis Results', fontsize=16, y=0.95)
125
 
126
  df = pd.DataFrame(features)
127
  if not df.empty:
128
  # Distribution plots
129
  df['area'].hist(ax=axes[0,0], bins=20, color='skyblue', edgecolor='black')
130
  axes[0,0].set_title('Cell Size Distribution')
131
+ axes[0,0].set_xlabel('Area (pixels)')
132
  axes[0,0].set_ylabel('Count')
133
 
134
  df['circularity'].hist(ax=axes[0,1], bins=20, color='lightgreen', edgecolor='black')
 
136
  axes[0,1].set_xlabel('Circularity')
137
  axes[0,1].set_ylabel('Count')
138
 
139
+ # Scatter plot
140
+ axes[1,0].scatter(df['area'], df['circularity'], alpha=0.6, c='purple')
141
+ axes[1,0].set_title('Area vs Circularity')
142
+ axes[1,0].set_xlabel('Area')
143
+ axes[1,0].set_ylabel('Circularity')
 
144
 
145
  # Box plot
146
  df.boxplot(column=['area', 'circularity'], ax=axes[1,1])
 
155
  transformed_image = apply_color_transformation(original_image, transform_type)
156
 
157
  return (
158
+ vis_img,
159
  transformed_image,
160
  fig,
161
  df
 
165
  print(f"Error processing image: {str(e)}")
166
  return None, None, None, None
167
 
168
+
169
+
170
  # Create Gradio interface
171
  with gr.Blocks(title="Advanced Cell Analysis Tool", theme=gr.themes.Soft()) as demo:
172
  gr.Markdown("""