LiangLabUMB commited on
Commit
5ca7d24
·
verified ·
1 Parent(s): 766d78d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -7
app.py CHANGED
@@ -241,7 +241,31 @@ def filter_mask_by_size(masks,minimum_pixels):
241
 
242
  return renumbered_masks, removed_count
243
 
 
 
 
 
 
 
 
 
 
 
244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  def rec_min_size(masks):
246
  num_cells = len(np.unique(masks)) - 1
247
  if num_cells <= 0:
@@ -250,7 +274,7 @@ def rec_min_size(masks):
250
  return int(round(mean_cell_size))
251
 
252
  @spaces.GPU
253
- def run_segmentation_editor(editor_data, model_choice, min_cell_size):
254
  """
255
  Runs cell segmentation using ImageEditor data.
256
  Returns initial segmentation overlay, counts, confluency, and also masks/image for state.
@@ -285,21 +309,34 @@ def run_segmentation_editor(editor_data, model_choice, min_cell_size):
285
  # Run Cellpose segmentation
286
  masks, flows, styles = model.eval(processed_image_np, diameter=None, channels=[0, 0])
287
 
288
-
 
 
289
  # Minimum size filtering
290
 
291
  recommend_min = rec_min_size(masks)
292
 
293
  if min_cell_size > 0:
294
- masks, removed_count = filter_mask_by_size(masks, min_cell_size)
295
- filter_msg = f"Removed {removed_count} small objects (< {min_cell_size} pixels).\n"
296
  else:
297
- removed_count = 0
298
  filter_msg=""
299
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  cell_count = len(np.unique(masks)) - 1
301
  confluency = measure_confluency(masks, processed_image_np)
302
-
303
  # Create a basic segmentation overlay (without viability)
304
  segmentation_overlay = processed_image_np.copy().astype(np.float32)
305
  if masks.max() > 0:
@@ -313,6 +350,7 @@ def run_segmentation_editor(editor_data, model_choice, min_cell_size):
313
 
314
  info_msg = f"Segmentation complete! Found {cell_count} cells.\n"
315
  info_msg += f"Confluency: {confluency:.1f}%\n"
 
316
  if region_coords:
317
  info_msg += f"Processed region: {region_coords[0]},{region_coords[1]} to {region_coords[2]},{region_coords[3]}\n"
318
  info_msg += f"Now adjust the Blue Threshold for viability assessment."
@@ -415,6 +453,13 @@ with gr.Blocks(
415
  label="Minimum Cell Size (pixels)",
416
 
417
  )
 
 
 
 
 
 
 
418
 
419
  segment_btn1 = gr.Button("🔬 Run Segmentation", variant="primary", size="lg")
420
 
@@ -451,7 +496,7 @@ with gr.Blocks(
451
  # Event handlers
452
  segment_btn1.click(
453
  fn=run_segmentation_editor,
454
- inputs=[image_editor, model_dropdown1, min_size_slider1],
455
  outputs=[cell_count_output1, overlay_output1, info_output1, viability_section1, masks_state, image_state, confluency_output1, min_size_slider1]
456
  ).then( # Chain the initial viability assessment after segmentation
457
  fn=update_viability_realtime,
 
241
 
242
  return renumbered_masks, removed_count
243
 
244
+ def filter_mask_by_maxsize(masks,maximum_pixels):
245
+ filtered_masks=masks.copy()
246
+ cell_ids = np.unique(masks)
247
+ cell_ids = cell_ids[cell_ids > 0]
248
+
249
+ removed_count = 0
250
+
251
+ for cell_id in cell_ids:
252
+ cell_mask = (masks == cell_id)
253
+ cell_pixels = np.count_nonzero(cell_mask)
254
 
255
+ if cell_pixels > maximum_pixels:
256
+ filtered_masks[cell_mask] = 0
257
+ removed_count +=1
258
+
259
+ unique_ids = np.unique(filtered_masks)
260
+ unique_ids = unique_ids[unique_ids > 0]
261
+
262
+ renumbered_masks = np.zeros_like(filtered_masks)
263
+ for new_id, old_id in enumerate(unique_ids, start=1):
264
+ renumbered_masks[filtered_masks == old_id] = new_id
265
+
266
+
267
+ return renumbered_masks, removed_count
268
+
269
  def rec_min_size(masks):
270
  num_cells = len(np.unique(masks)) - 1
271
  if num_cells <= 0:
 
274
  return int(round(mean_cell_size))
275
 
276
  @spaces.GPU
277
+ def run_segmentation_editor(editor_data, model_choice, min_cell_size, max_cell_size):
278
  """
279
  Runs cell segmentation using ImageEditor data.
280
  Returns initial segmentation overlay, counts, confluency, and also masks/image for state.
 
309
  # Run Cellpose segmentation
310
  masks, flows, styles = model.eval(processed_image_np, diameter=None, channels=[0, 0])
311
 
312
+ removed_small = 0
313
+ removed_large = 0
314
+
315
  # Minimum size filtering
316
 
317
  recommend_min = rec_min_size(masks)
318
 
319
  if min_cell_size > 0:
320
+ masks, removed_small = filter_mask_by_size(masks, min_cell_size)
321
+ filter_msg = f"Removed {removed_small} small objects (< {min_cell_size} pixels).\n"
322
  else:
323
+ removed_small = 0
324
  filter_msg=""
325
 
326
+
327
+
328
+ # Maximum size filtering
329
+ if max_cell_size > 0:
330
+ masks, removed_large = filter_mask_by_maxsize(masks, max_cell_size)
331
+ filter_msg = f"Removed {removed_large} large objects (> {max_cell_size} pixels).\n"
332
+ else:
333
+ removed_large = 0
334
+ filter_msg=""
335
+
336
+ removed_count = removed_small + removed_large
337
+
338
  cell_count = len(np.unique(masks)) - 1
339
  confluency = measure_confluency(masks, processed_image_np)
 
340
  # Create a basic segmentation overlay (without viability)
341
  segmentation_overlay = processed_image_np.copy().astype(np.float32)
342
  if masks.max() > 0:
 
350
 
351
  info_msg = f"Segmentation complete! Found {cell_count} cells.\n"
352
  info_msg += f"Confluency: {confluency:.1f}%\n"
353
+ info_msg = filter_msg + info_msg
354
  if region_coords:
355
  info_msg += f"Processed region: {region_coords[0]},{region_coords[1]} to {region_coords[2]},{region_coords[3]}\n"
356
  info_msg += f"Now adjust the Blue Threshold for viability assessment."
 
453
  label="Minimum Cell Size (pixels)",
454
 
455
  )
456
+ max_size_slider1 = gr.Slider(
457
+ minimum=0,
458
+ maximum=500,
459
+ value=500,
460
+ step=10,
461
+ label="Maximum Cell Size (pixels)",
462
+ )
463
 
464
  segment_btn1 = gr.Button("🔬 Run Segmentation", variant="primary", size="lg")
465
 
 
496
  # Event handlers
497
  segment_btn1.click(
498
  fn=run_segmentation_editor,
499
+ inputs=[image_editor, model_dropdown1, min_size_slider1, max_size_slider1],
500
  outputs=[cell_count_output1, overlay_output1, info_output1, viability_section1, masks_state, image_state, confluency_output1, min_size_slider1]
501
  ).then( # Chain the initial viability assessment after segmentation
502
  fn=update_viability_realtime,