Shengxiao0709 commited on
Commit
78c904a
·
verified ·
1 Parent(s): 7a54c54

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -31
app.py CHANGED
@@ -136,29 +136,11 @@ def colorize_mask(mask: np.ndarray, num_colors: int = 512) -> np.ndarray:
136
  color_idx = mask % num_colors
137
  return palette_arr[color_idx]
138
 
139
- def overlay_instances(img, mask, alpha=0.5, cmap_name="tab20"):
140
- """叠加实例颜色"""
141
- img = img.astype(np.float32)
142
- if len(img.shape) == 2:
143
- img = np.stack([img]*3, axis=-1)
144
- if img.max() > 1.5:
145
- img = img / 255.0
146
-
147
- overlay = img.copy()
148
- cmap = cm.get_cmap(cmap_name, np.max(mask) + 1)
149
-
150
- for inst_id in np.unique(mask):
151
- if inst_id == 0:
152
- continue
153
- color = np.array(cmap(inst_id)[:3])
154
- overlay[mask == inst_id] = (1 - alpha) * overlay[mask == inst_id] + alpha * color
155
-
156
- return overlay
157
-
158
  # ===== 分割功能 =====
159
  def segment_with_choice(use_box_choice, annot_value):
160
- """分割主函数 - 固定使用Overlay模式,同时返回原始mask"""
161
  if annot_value is None or len(annot_value) < 1:
 
162
  return None, None
163
 
164
  img_path = annot_value[0]
@@ -176,7 +158,7 @@ def segment_with_choice(use_box_choice, annot_value):
176
  # 运行分割模型
177
  try:
178
  mask = run_seg(SEG_MODEL, img_path, box=box_array, device=SEG_DEVICE)
179
- print("📏 mask shape:", mask.shape, "unique ids:", np.unique(mask))
180
  except Exception as e:
181
  print(f"❌ 推理失败: {str(e)}")
182
  return None, None
@@ -189,26 +171,55 @@ def segment_with_choice(use_box_choice, annot_value):
189
 
190
  # 读取原图
191
  try:
192
- img = Image.open(img_path).convert("RGB").resize(mask.shape[::-1], resample=Image.BILINEAR)
193
- img_np = np.array(img).astype(np.float32)
 
 
 
 
 
 
 
194
  if img_np.max() > 1.5:
195
- img_np /= 255.0
196
  except Exception as e:
197
- print(f"❌ 图像读取失败: {str(e)}")
198
  return None, None
199
 
200
- inst_mask = mask.astype(np.int32)
 
201
  unique_ids = np.unique(inst_mask)
202
  num_instances = len(unique_ids[unique_ids != 0])
203
- print(f"✅ 实例数量: {num_instances}")
204
 
205
  if num_instances == 0:
 
206
  return Image.new("RGB", mask.shape[::-1], (255, 0, 0)), None
207
 
208
- # 使用Overlay模式可视化
209
- overlay = overlay_instances(img_np, inst_mask, alpha=0.5, cmap_name="tab20")
210
- overlay_img = Image.fromarray((overlay * 255).astype(np.uint8))
211
- return overlay_img, temp_mask_file.name
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
  # ===== 计数功能 =====
214
  def count_cells_handler(image_path):
 
136
  color_idx = mask % num_colors
137
  return palette_arr[color_idx]
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  # ===== 分割功能 =====
140
  def segment_with_choice(use_box_choice, annot_value):
141
+ """分割主函数 - 每个实例不同颜色+轮廓"""
142
  if annot_value is None or len(annot_value) < 1:
143
+ print("❌ No annotation input")
144
  return None, None
145
 
146
  img_path = annot_value[0]
 
158
  # 运行分割模型
159
  try:
160
  mask = run_seg(SEG_MODEL, img_path, box=box_array, device=SEG_DEVICE)
161
+ print("📏 mask shape:", mask.shape, "dtype:", mask.dtype, "unique:", np.unique(mask))
162
  except Exception as e:
163
  print(f"❌ 推理失败: {str(e)}")
164
  return None, None
 
171
 
172
  # 读取原图
173
  try:
174
+ img = Image.open(img_path)
175
+ print("📷 Image mode:", img.mode, "size:", img.size)
176
+ except Exception as e:
177
+ print(f"❌ Failed to open image: {e}")
178
+ return None, None
179
+
180
+ try:
181
+ img_rgb = img.convert("RGB").resize(mask.shape[::-1], resample=Image.BILINEAR)
182
+ img_np = np.array(img_rgb, dtype=np.float32)
183
  if img_np.max() > 1.5:
184
+ img_np = img_np / 255.0
185
  except Exception as e:
186
+ print(f"❌ Error in image conversion/resizing: {e}")
187
  return None, None
188
 
189
+ mask_np = np.array(mask)
190
+ inst_mask = mask_np.astype(np.int32)
191
  unique_ids = np.unique(inst_mask)
192
  num_instances = len(unique_ids[unique_ids != 0])
193
+ print(f"✅ Instance IDs found: {unique_ids}, Total instances: {num_instances}")
194
 
195
  if num_instances == 0:
196
+ print("⚠️ No instance found, returning dummy red image")
197
  return Image.new("RGB", mask.shape[::-1], (255, 0, 0)), None
198
 
199
+ # ==== Color Overlay (每个实例一个颜色) ====
200
+ overlay = img_np.copy()
201
+ alpha = 0.5
202
+ cmap = cm.get_cmap("nipy_spectral", num_instances + 1)
203
+
204
+ for inst_id in np.unique(inst_mask):
205
+ if inst_id == 0:
206
+ continue
207
+ binary_mask = (inst_mask == inst_id).astype(np.uint8)
208
+ color = np.array(cmap(inst_id / (num_instances + 1))[:3]) # RGB only, ignore alpha
209
+ overlay[binary_mask == 1] = (1 - alpha) * overlay[binary_mask == 1] + alpha * color
210
+
211
+ # 绘制轮廓
212
+ contours = measure.find_contours(binary_mask, 0.5)
213
+ for contour in contours:
214
+ contour = contour.astype(np.int32)
215
+ # 确保坐标在范围内
216
+ valid_y = np.clip(contour[:, 0], 0, overlay.shape[0] - 1)
217
+ valid_x = np.clip(contour[:, 1], 0, overlay.shape[1] - 1)
218
+ overlay[valid_y, valid_x] = [1.0, 1.0, 0.0] # 黄色轮廓
219
+
220
+ overlay = np.clip(overlay * 255.0, 0, 255).astype(np.uint8)
221
+
222
+ return Image.fromarray(overlay), temp_mask_file.name
223
 
224
  # ===== 计数功能 =====
225
  def count_cells_handler(image_path):