Shengxiao0709 commited on
Commit
79f5edd
·
verified ·
1 Parent(s): 66a0cfd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -32
app.py CHANGED
@@ -429,32 +429,27 @@ def colorize_mask(mask: np.ndarray, num_colors: int = 512) -> np.ndarray:
429
 
430
  # ===== 推理 + 实例彩色可视化 =====
431
  def segment_with_choice(use_box_choice, annot_value, mode="Overlay"):
432
- """分割推理 + 可视化,与原始逻辑完全对齐"""
433
  if annot_value is None or len(annot_value) < 1:
434
- print("❌ No annotation input")
435
  return None, "⚠️ 请先上传图像"
436
 
437
  img_path = annot_value[0]
438
  bboxes = annot_value[1] if len(annot_value) > 1 else []
439
 
440
- print(f"🖼️ Image path: {img_path}")
441
  box_array = None
442
  if use_box_choice == "Yes" and bboxes:
443
  box = parse_first_bbox(bboxes)
444
  if box:
445
  xmin, ymin, xmax, ymax = map(int, box)
446
  box_array = [[xmin, ymin, xmax, ymax]]
447
- print(f"📦 Using box: {box_array}")
448
 
449
  try:
450
- # 调用分割模型
451
  mask = run_seg(SEG_MODEL, img_path, box=box_array, device=SEG_DEVICE)
452
- print("📏 Mask shape:", mask.shape, "dtype:", mask.dtype, "unique:", np.unique(mask))
 
453
  except Exception as e:
454
- print(f"❌ Error during inference: {e}")
455
- return None, f"分割失败: {str(e)}"
456
 
457
- # 读取原图
458
  try:
459
  img = Image.open(img_path).convert("RGB")
460
  img_rgb = img.resize(mask.shape[::-1], resample=Image.BILINEAR)
@@ -462,50 +457,44 @@ def segment_with_choice(use_box_choice, annot_value, mode="Overlay"):
462
  if img_np.max() > 1.5:
463
  img_np = img_np / 255.0
464
  except Exception as e:
465
- print(f"❌ Failed to open/convert image: {e}")
466
- return None, f"图像读取失败: {str(e)}"
467
 
468
- # 生成实例掩码
469
- mask_np = np.array(mask)
470
- inst_mask = mask_np.astype(np.int32)
471
  unique_ids = np.unique(inst_mask)
472
  num_instances = len(unique_ids[unique_ids != 0])
473
- print(f"✅ Instance IDs found: {unique_ids}, Total instances: {num_instances}")
474
 
475
  if num_instances == 0:
476
- print("⚠️ No instance found, returning dummy red image")
477
- return Image.new("RGB", mask.shape[::-1], (255, 0, 0)), "⚠️ 未检测到细胞"
478
 
479
- # ==== 🎨 Overlay (每个实例一个颜+ 黄色轮廓) ====
 
 
 
480
  overlay = img_np.copy()
481
- alpha = 0.75 # 增强透明度,更清晰
482
- cmap = cm.get_cmap("tab20", num_instances + 1) # 亮色系更清楚
483
 
484
- for inst_id in np.unique(inst_mask):
 
485
  if inst_id == 0:
486
  continue
487
  binary_mask = (inst_mask == inst_id).astype(np.uint8)
488
- color = np.array(cmap(inst_id / (num_instances + 1))[:3])
489
- overlay[binary_mask == 1] = (1 - alpha) * overlay[binary_mask == 1] + alpha * color
490
-
491
- # 🟡 绘制粗黄色轮廓
492
  contours = measure.find_contours(binary_mask, 0.5)
493
  for contour in contours:
494
  contour = contour.astype(np.int32)
495
  for dy in [-1, 0, 1]:
496
  for dx in [-1, 0, 1]:
497
- yy = np.clip(contour[:, 0] + dy, 0, overlay.shape[0] - 1).astype(np.int32)
498
- xx = np.clip(contour[:, 1] + dx, 0, overlay.shape[1] - 1).astype(np.int32)
499
- overlay[yy, xx] = [1.0, 1.0, 0.0] # 缘线
500
 
501
- overlay = np.clip(overlay * 255.0, 0, 255).astype(np.uint8)
502
  result_text = f"✅ 检测到 {num_instances} 个细胞"
503
 
504
  if mode == "Instance Mask Only":
505
- # 输出纯彩色 mask
506
- return Image.fromarray(colorize_mask(inst_mask, num_colors=512)), result_text
507
 
508
- return Image.fromarray(overlay), result_text
509
 
510
  # ===== 计数功能 =====
511
  def count_cells_handler(image_path):
 
429
 
430
  # ===== 推理 + 实例彩色可视化 =====
431
  def segment_with_choice(use_box_choice, annot_value, mode="Overlay"):
432
+ """分割推理 + 可视化(更深颜色、更清晰区分)"""
433
  if annot_value is None or len(annot_value) < 1:
 
434
  return None, "⚠️ 请先上传图像"
435
 
436
  img_path = annot_value[0]
437
  bboxes = annot_value[1] if len(annot_value) > 1 else []
438
 
 
439
  box_array = None
440
  if use_box_choice == "Yes" and bboxes:
441
  box = parse_first_bbox(bboxes)
442
  if box:
443
  xmin, ymin, xmax, ymax = map(int, box)
444
  box_array = [[xmin, ymin, xmax, ymax]]
 
445
 
446
  try:
 
447
  mask = run_seg(SEG_MODEL, img_path, box=box_array, device=SEG_DEVICE)
448
+ if mask is None:
449
+ return None, "❌ 分割失败"
450
  except Exception as e:
451
+ return None, f"❌ 推理错误: {e}"
 
452
 
 
453
  try:
454
  img = Image.open(img_path).convert("RGB")
455
  img_rgb = img.resize(mask.shape[::-1], resample=Image.BILINEAR)
 
457
  if img_np.max() > 1.5:
458
  img_np = img_np / 255.0
459
  except Exception as e:
460
+ return None, f"❌ 图像处理失败: {e}"
 
461
 
462
+ inst_mask = np.array(mask).astype(np.int32)
 
 
463
  unique_ids = np.unique(inst_mask)
464
  num_instances = len(unique_ids[unique_ids != 0])
 
465
 
466
  if num_instances == 0:
467
+ return Image.new("RGB", mask.shape[::-1], (255, 200, 200)), "⚠️ 未检测到细胞"
 
468
 
469
+ # ===== 🎨 mask 生成 =====
470
+ color_mask = colorize_mask(inst_mask, num_colors=512).astype(np.float32) / 255.0
471
+
472
+ # ===== 🌈 半透明叠加在原图上 =====
473
  overlay = img_np.copy()
474
+ alpha = 0.6
475
+ blended = (1 - alpha) * overlay + alpha * color_mask
476
 
477
+ # ===== 🔶 黄色轮廓线描边每个实例 =====
478
+ for inst_id in unique_ids:
479
  if inst_id == 0:
480
  continue
481
  binary_mask = (inst_mask == inst_id).astype(np.uint8)
 
 
 
 
482
  contours = measure.find_contours(binary_mask, 0.5)
483
  for contour in contours:
484
  contour = contour.astype(np.int32)
485
  for dy in [-1, 0, 1]:
486
  for dx in [-1, 0, 1]:
487
+ yy = np.clip(contour[:, 0] + dy, 0, blended.shape[0] - 1).astype(np.int32)
488
+ xx = np.clip(contour[:, 1] + dx, 0, blended.shape[1] - 1).astype(np.int32)
489
+ blended[yy, xx] = [1.0, 1.0, 0.0] # 黄色
490
 
491
+ blended = np.clip(blended * 255.0, 0, 255).astype(np.uint8)
492
  result_text = f"✅ 检测到 {num_instances} 个细胞"
493
 
494
  if mode == "Instance Mask Only":
495
+ return Image.fromarray((color_mask * 255).astype(np.uint8)), result_text
 
496
 
497
+ return Image.fromarray(blended), result_text
498
 
499
  # ===== 计数功能 =====
500
  def count_cells_handler(image_path):