ibrahim313 commited on
Commit
cd32abe
·
verified ·
1 Parent(s): c2460b3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -68
app.py CHANGED
@@ -2,12 +2,11 @@ import cv2
2
  import numpy as np
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)
@@ -15,45 +14,48 @@ def detect_blood_cells(image):
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"""
@@ -61,64 +63,68 @@ def process_image(image, transform_type):
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 with default style
122
  plt.style.use('default')
123
  fig, axes = plt.subplots(2, 2, figsize=(15, 12))
124
  fig.suptitle('Blood Cell Analysis Results', fontsize=16, y=0.95)
@@ -139,11 +145,14 @@ def process_image(image, transform_type):
139
  axes[0,1].grid(True, alpha=0.3)
140
 
141
  # Scatter plot
142
- axes[1,0].scatter(df['area'], df['circularity'], alpha=0.6, c='purple')
143
- axes[1,0].set_title('Area vs Circularity')
 
 
144
  axes[1,0].set_xlabel('Area')
145
- axes[1,0].set_ylabel('Circularity')
146
  axes[1,0].grid(True, alpha=0.3)
 
147
 
148
  # Box plot
149
  df.boxplot(column=['area', 'circularity'], ax=axes[1,1])
@@ -168,7 +177,7 @@ def process_image(image, transform_type):
168
  except Exception as e:
169
  print(f"Error processing image: {str(e)}")
170
  import traceback
171
- traceback.print_exc() # This will print the full error trace
172
  return None, None, None, None
173
 
174
 
 
2
  import numpy as np
3
  import pandas as pd
4
  import gradio as gr
 
5
  import matplotlib.pyplot as plt
6
  from datetime import datetime
7
 
8
  def detect_blood_cells(image):
9
+ """Optimized function for blood cell detection"""
10
  # Convert to RGB if grayscale
11
  if len(image.shape) == 2:
12
  image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
 
14
  # Convert to HSV color space
15
  hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
16
 
17
+ # Optimized red color ranges for blood cells
18
+ lower_red1 = np.array([0, 100, 100]) # Increased saturation threshold
 
19
  upper_red1 = np.array([10, 255, 255])
20
+ lower_red2 = np.array([160, 100, 100]) # Increased saturation threshold
21
  upper_red2 = np.array([180, 255, 255])
22
 
23
+ # Create masks for red color
24
  mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
25
  mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
26
  mask = mask1 + mask2
27
+
28
+ # Enhanced noise removal
29
+ kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
30
+ mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=1)
31
  mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=2)
32
 
33
+ # Apply distance transform to separate touching cells
34
+ dist_transform = cv2.distanceTransform(mask, cv2.DIST_L2, 5)
35
+ _, sure_fg = cv2.threshold(dist_transform, 0.5 * dist_transform.max(), 255, 0)
36
+ sure_fg = np.uint8(sure_fg)
37
 
38
+ # Find connected components
39
+ _, markers = cv2.connectedComponents(sure_fg)
40
+
41
+ # Find contours with hierarchy to handle nested contours
42
+ contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
 
43
 
44
+ # Filter contours based on area and circularity
45
+ filtered_contours = []
46
+ for contour in contours:
47
+ area = cv2.contourArea(contour)
48
+ perimeter = cv2.arcLength(contour, True)
49
+ if perimeter == 0:
50
+ continue
51
+
52
+ circularity = 4 * np.pi * area / (perimeter * perimeter)
53
+
54
+ # Optimized thresholds for your specific images
55
+ if 500 < area < 2500 and circularity > 0.8: # Adjusted thresholds
56
+ filtered_contours.append(contour)
57
+
58
+ return filtered_contours, markers
59
 
60
  def process_image(image, transform_type):
61
  """Process uploaded image and extract blood cell features"""
 
63
  return None, None, None, None
64
 
65
  try:
66
+ # Store original image
67
  original_image = image.copy()
68
 
69
  # Detect blood cells
70
+ contours, markers = detect_blood_cells(image)
71
 
72
  # Extract features
73
  features = []
74
  for i, contour in enumerate(contours, 1):
75
  area = cv2.contourArea(contour)
76
+ perimeter = cv2.arcLength(contour, True)
77
+ circularity = 4 * np.pi * area / (perimeter * perimeter)
78
+
79
+ # Calculate centroid
80
+ M = cv2.moments(contour)
81
+ if M["m00"] != 0:
82
+ cx = int(M["m10"] / M["m00"])
83
+ cy = int(M["m01"] / M["m00"])
84
+
85
+ # Extract mean color intensity
86
+ mask = np.zeros(image.shape[:2], dtype=np.uint8)
87
+ cv2.drawContours(mask, [contour], -1, 255, -1)
88
+ mean_intensity = cv2.mean(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY), mask=mask)[0]
89
 
90
+ features.append({
91
+ 'label': i,
92
+ 'area': area,
93
+ 'perimeter': perimeter,
94
+ 'circularity': circularity,
95
+ 'mean_intensity': mean_intensity,
96
+ 'centroid_x': cx,
97
+ 'centroid_y': cy
98
+ })
 
 
 
 
 
 
99
 
100
  # Create visualization
101
  vis_img = image.copy()
102
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
103
 
104
+ # Draw contours and labels with enhanced visibility
105
  for feature in features:
106
+ i = feature['label'] - 1
107
+ cv2.drawContours(vis_img, contours, i, (0, 255, 0), 2)
108
 
109
  # Add cell labels
110
  x = feature['centroid_x']
111
  y = feature['centroid_y']
112
  # White outline
113
  cv2.putText(vis_img, str(feature['label']),
114
+ (x-10, y), cv2.FONT_HERSHEY_SIMPLEX,
115
+ 0.4, (255, 255, 255), 2)
116
  # Red text
117
  cv2.putText(vis_img, str(feature['label']),
118
+ (x-10, y), cv2.FONT_HERSHEY_SIMPLEX,
119
+ 0.4, (0, 0, 255), 1)
120
 
121
+ # Add timestamp and cell count with better positioning
122
+ info_text = f"Analyzed: {timestamp} | Cells Detected: {len(features)}"
123
+ cv2.putText(vis_img, info_text,
124
+ (10, 25), cv2.FONT_HERSHEY_SIMPLEX,
125
+ 0.6, (255, 255, 255), 2)
126
 
127
+ # Create analysis plots
128
  plt.style.use('default')
129
  fig, axes = plt.subplots(2, 2, figsize=(15, 12))
130
  fig.suptitle('Blood Cell Analysis Results', fontsize=16, y=0.95)
 
145
  axes[0,1].grid(True, alpha=0.3)
146
 
147
  # Scatter plot
148
+ scatter = axes[1,0].scatter(df['area'], df['mean_intensity'],
149
+ c=df['circularity'], cmap='viridis',
150
+ alpha=0.6)
151
+ axes[1,0].set_title('Area vs Intensity')
152
  axes[1,0].set_xlabel('Area')
153
+ axes[1,0].set_ylabel('Mean Intensity')
154
  axes[1,0].grid(True, alpha=0.3)
155
+ plt.colorbar(scatter, ax=axes[1,0], label='Circularity')
156
 
157
  # Box plot
158
  df.boxplot(column=['area', 'circularity'], ax=axes[1,1])
 
177
  except Exception as e:
178
  print(f"Error processing image: {str(e)}")
179
  import traceback
180
+ traceback.print_exc()
181
  return None, None, None, None
182
 
183