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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -11
app.py CHANGED
@@ -157,9 +157,9 @@ def overlay_instances(img, mask, alpha=0.5, cmap_name="tab20"):
157
 
158
  # ===== 分割功能 =====
159
  def segment_with_choice(use_box_choice, annot_value):
160
- """分割主函数 - 固定使用Overlay模式"""
161
  if annot_value is None or len(annot_value) < 1:
162
- return None
163
 
164
  img_path = annot_value[0]
165
  bboxes = annot_value[1] if len(annot_value) > 1 else []
@@ -179,7 +179,13 @@ def segment_with_choice(use_box_choice, annot_value):
179
  print("📏 mask shape:", mask.shape, "unique ids:", np.unique(mask))
180
  except Exception as e:
181
  print(f"❌ 推理失败: {str(e)}")
182
- return None
 
 
 
 
 
 
183
 
184
  # 读取原图
185
  try:
@@ -189,7 +195,7 @@ def segment_with_choice(use_box_choice, annot_value):
189
  img_np /= 255.0
190
  except Exception as e:
191
  print(f"❌ 图像读取失败: {str(e)}")
192
- return None
193
 
194
  inst_mask = mask.astype(np.int32)
195
  unique_ids = np.unique(inst_mask)
@@ -197,16 +203,16 @@ def segment_with_choice(use_box_choice, annot_value):
197
  print(f"✅ 实例数量: {num_instances}")
198
 
199
  if num_instances == 0:
200
- return Image.new("RGB", mask.shape[::-1], (255, 0, 0))
201
 
202
  # 使用Overlay模式可视化
203
  overlay = overlay_instances(img_np, inst_mask, alpha=0.5, cmap_name="tab20")
204
  overlay_img = Image.fromarray((overlay * 255).astype(np.uint8))
205
- return overlay_img
206
 
207
  # ===== 计数功能 =====
208
  def count_cells_handler(image_path):
209
- """计数处理函数"""
210
  if image_path is None:
211
  return None, "⚠️ 请先上传图像"
212
 
@@ -225,12 +231,34 @@ def count_cells_handler(image_path):
225
  return None, f"❌ 计数失败: {result['error']}"
226
 
227
  count = result['count']
228
- viz_path = result['visualized_path']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  result_text = f"✅ 检测到 {count:.1f} 个细胞"
230
 
231
  print(f"✅ Counting done - Count: {count:.1f}")
232
 
233
- return viz_path, result_text
234
 
235
  except Exception as e:
236
  print(f"❌ Counting error: {e}")
@@ -369,6 +397,12 @@ with gr.Blocks(title="Microscopy Analysis Suite", theme=gr.themes.Soft()) as dem
369
  height=400
370
  )
371
 
 
 
 
 
 
 
372
  # 满意度评分
373
  score_slider = gr.Slider(
374
  minimum=1,
@@ -398,7 +432,7 @@ with gr.Blocks(title="Microscopy Analysis Suite", theme=gr.themes.Soft()) as dem
398
  run_seg_btn.click(
399
  fn=segment_with_choice,
400
  inputs=[use_box_radio, annotator],
401
- outputs=seg_output
402
  )
403
 
404
  # 初始化Gallery显示
@@ -486,7 +520,7 @@ with gr.Blocks(title="Microscopy Analysis Suite", theme=gr.themes.Soft()) as dem
486
 
487
  with gr.Column(scale=2):
488
  count_output = gr.Image(
489
- label="📸 计数结果",
490
  type="filepath",
491
  height=500
492
  )
 
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]
165
  bboxes = annot_value[1] if len(annot_value) > 1 else []
 
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
183
+
184
+ # 保存原始mask为TIF文件
185
+ temp_mask_file = tempfile.NamedTemporaryFile(delete=False, suffix=".tif")
186
+ mask_img = Image.fromarray(mask.astype(np.uint16))
187
+ mask_img.save(temp_mask_file.name)
188
+ print(f"💾 原始mask保存到: {temp_mask_file.name}")
189
 
190
  # 读取原图
191
  try:
 
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)
 
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):
215
+ """计数处理函数 - 只返回密度图"""
216
  if image_path is None:
217
  return None, "⚠️ 请先上传图像"
218
 
 
231
  return None, f"❌ 计数失败: {result['error']}"
232
 
233
  count = result['count']
234
+
235
+ # 只提取密度图部分(假设visualized_path是拼接图,我们只要右半部分)
236
+ viz_path = result.get('visualized_path')
237
+
238
+ # 如果有density_map_path,直接使用
239
+ if 'density_map_path' in result:
240
+ density_path = result['density_map_path']
241
+ elif viz_path and os.path.exists(viz_path):
242
+ # 如果是拼接图,提取右半部分(密度图)
243
+ try:
244
+ viz_img = Image.open(viz_path)
245
+ w, h = viz_img.size
246
+ # 取右半部分
247
+ density_img = viz_img.crop((w//2, 0, w, h))
248
+ # 保存为新文件
249
+ temp_density = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
250
+ density_img.save(temp_density.name)
251
+ density_path = temp_density.name
252
+ except:
253
+ density_path = viz_path
254
+ else:
255
+ density_path = viz_path
256
+
257
  result_text = f"✅ 检测到 {count:.1f} 个细胞"
258
 
259
  print(f"✅ Counting done - Count: {count:.1f}")
260
 
261
+ return density_path, result_text
262
 
263
  except Exception as e:
264
  print(f"❌ Counting error: {e}")
 
397
  height=400
398
  )
399
 
400
+ # 下载原始预测结果
401
+ download_mask_btn = gr.File(
402
+ label="📥 下载原始预测 (.tif 格式)",
403
+ visible=True
404
+ )
405
+
406
  # 满意度评分
407
  score_slider = gr.Slider(
408
  minimum=1,
 
432
  run_seg_btn.click(
433
  fn=segment_with_choice,
434
  inputs=[use_box_radio, annotator],
435
+ outputs=[seg_output, download_mask_btn]
436
  )
437
 
438
  # 初始化Gallery显示
 
520
 
521
  with gr.Column(scale=2):
522
  count_output = gr.Image(
523
+ label="📸 密度图",
524
  type="filepath",
525
  height=500
526
  )