Update app.py
Browse files
app.py
CHANGED
|
@@ -126,15 +126,20 @@ def calculate_blue_intensity(image_np, masks):
|
|
| 126 |
|
| 127 |
def create_viability_overlay(image_np, masks, blue_threshold):
|
| 128 |
"""Create overlay showing live/dead cells based on blue threshold"""
|
| 129 |
-
global current_masks, current_image
|
| 130 |
|
| 131 |
if masks is None or image_np is None:
|
| 132 |
return None, 0, 0
|
| 133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
# Calculate blue intensities
|
| 135 |
cell_blue_intensities = calculate_blue_intensity(image_np, masks)
|
| 136 |
|
| 137 |
-
# Create overlay
|
| 138 |
overlay = image_np.copy().astype(np.float32)
|
| 139 |
|
| 140 |
live_count = 0
|
|
@@ -154,11 +159,11 @@ def create_viability_overlay(image_np, masks, blue_threshold):
|
|
| 154 |
live_count += 1
|
| 155 |
|
| 156 |
# Blend with original image
|
| 157 |
-
alpha = 0.
|
| 158 |
-
|
| 159 |
-
|
| 160 |
|
| 161 |
-
return Image.fromarray(
|
| 162 |
|
| 163 |
@spaces.GPU
|
| 164 |
def segment_cells(editor_data, model_choice, crop_coords=None):
|
|
@@ -261,22 +266,34 @@ def update_viability_assessment(blue_threshold):
|
|
| 261 |
return None, 0, 0, "Please run segmentation first"
|
| 262 |
|
| 263 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
# Create viability overlay
|
| 265 |
viability_overlay, live_count, dead_count = create_viability_overlay(
|
| 266 |
current_image, current_masks, blue_threshold
|
| 267 |
)
|
| 268 |
|
| 269 |
total_count = live_count + dead_count
|
| 270 |
-
viability_info = f"
|
|
|
|
| 271 |
|
| 272 |
if total_count > 0:
|
| 273 |
viability_percentage = (live_count / total_count) * 100
|
| 274 |
-
viability_info += f"
|
|
|
|
|
|
|
| 275 |
|
| 276 |
return viability_overlay, live_count, dead_count, viability_info
|
| 277 |
|
| 278 |
except Exception as e:
|
| 279 |
-
return None, 0, 0, f"Error in viability assessment: {str(e)}"
|
| 280 |
|
| 281 |
@spaces.GPU
|
| 282 |
def segment_with_coords(image, model_choice, crop_coords):
|
|
@@ -414,6 +431,10 @@ with gr.Blocks(title="Cell Counter with Real-time Viability Assessment", theme=g
|
|
| 414 |
fn=segment_cells,
|
| 415 |
inputs=[image_editor, model_dropdown1],
|
| 416 |
outputs=[cell_count_output1, overlay_output1, info_output1, viability_section1]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 417 |
)
|
| 418 |
|
| 419 |
blue_threshold_slider1.change(
|
|
@@ -473,6 +494,10 @@ with gr.Blocks(title="Cell Counter with Real-time Viability Assessment", theme=g
|
|
| 473 |
fn=segment_with_coords,
|
| 474 |
inputs=[image_input, model_dropdown2, coord_input],
|
| 475 |
outputs=[cell_count_output2, overlay_output2, info_output2, viability_section2]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 476 |
)
|
| 477 |
|
| 478 |
blue_threshold_slider2.change(
|
|
|
|
| 126 |
|
| 127 |
def create_viability_overlay(image_np, masks, blue_threshold):
|
| 128 |
"""Create overlay showing live/dead cells based on blue threshold"""
|
|
|
|
| 129 |
|
| 130 |
if masks is None or image_np is None:
|
| 131 |
return None, 0, 0
|
| 132 |
|
| 133 |
+
# Ensure image is RGB
|
| 134 |
+
if len(image_np.shape) == 2:
|
| 135 |
+
image_np = cv2.cvtColor(image_np, cv2.COLOR_GRAY2RGB)
|
| 136 |
+
elif len(image_np.shape) == 3 and image_np.shape[2] == 4:
|
| 137 |
+
image_np = cv2.cvtColor(image_np, cv2.COLOR_RGBA2RGB)
|
| 138 |
+
|
| 139 |
# Calculate blue intensities
|
| 140 |
cell_blue_intensities = calculate_blue_intensity(image_np, masks)
|
| 141 |
|
| 142 |
+
# Create overlay - start with original image
|
| 143 |
overlay = image_np.copy().astype(np.float32)
|
| 144 |
|
| 145 |
live_count = 0
|
|
|
|
| 159 |
live_count += 1
|
| 160 |
|
| 161 |
# Blend with original image
|
| 162 |
+
alpha = 0.6 # Increased alpha for better visibility
|
| 163 |
+
final_overlay = (1 - alpha) * image_np.astype(np.float32) + alpha * overlay
|
| 164 |
+
final_overlay = np.clip(final_overlay, 0, 255).astype(np.uint8)
|
| 165 |
|
| 166 |
+
return Image.fromarray(final_overlay), live_count, dead_count
|
| 167 |
|
| 168 |
@spaces.GPU
|
| 169 |
def segment_cells(editor_data, model_choice, crop_coords=None):
|
|
|
|
| 266 |
return None, 0, 0, "Please run segmentation first"
|
| 267 |
|
| 268 |
try:
|
| 269 |
+
# Debug information
|
| 270 |
+
unique_cells = np.unique(current_masks)
|
| 271 |
+
total_cells = len(unique_cells) - 1 # Subtract background
|
| 272 |
+
|
| 273 |
+
debug_info = f"Debug - Total cells found: {total_cells}\n"
|
| 274 |
+
debug_info += f"Image shape: {current_image.shape}\n"
|
| 275 |
+
debug_info += f"Masks shape: {current_masks.shape}\n"
|
| 276 |
+
debug_info += f"Unique mask values: {unique_cells[:10]}...\n" # Show first 10
|
| 277 |
+
|
| 278 |
# Create viability overlay
|
| 279 |
viability_overlay, live_count, dead_count = create_viability_overlay(
|
| 280 |
current_image, current_masks, blue_threshold
|
| 281 |
)
|
| 282 |
|
| 283 |
total_count = live_count + dead_count
|
| 284 |
+
viability_info = f"Blue threshold: {blue_threshold}\n"
|
| 285 |
+
viability_info += f"Total cells: {total_count}\nLive (green): {live_count}\nDead (red): {dead_count}\n"
|
| 286 |
|
| 287 |
if total_count > 0:
|
| 288 |
viability_percentage = (live_count / total_count) * 100
|
| 289 |
+
viability_info += f"Viability: {viability_percentage:.1f}%\n"
|
| 290 |
+
|
| 291 |
+
viability_info += f"\n{debug_info}"
|
| 292 |
|
| 293 |
return viability_overlay, live_count, dead_count, viability_info
|
| 294 |
|
| 295 |
except Exception as e:
|
| 296 |
+
return None, 0, 0, f"Error in viability assessment: {str(e)}\nMasks available: {current_masks is not None}\nImage available: {current_image is not None}"
|
| 297 |
|
| 298 |
@spaces.GPU
|
| 299 |
def segment_with_coords(image, model_choice, crop_coords):
|
|
|
|
| 431 |
fn=segment_cells,
|
| 432 |
inputs=[image_editor, model_dropdown1],
|
| 433 |
outputs=[cell_count_output1, overlay_output1, info_output1, viability_section1]
|
| 434 |
+
).then( # Chain the viability assessment after segmentation
|
| 435 |
+
fn=update_viability_assessment,
|
| 436 |
+
inputs=[blue_threshold_slider1],
|
| 437 |
+
outputs=[viability_overlay1, live_count_output1, dead_count_output1, viability_info1]
|
| 438 |
)
|
| 439 |
|
| 440 |
blue_threshold_slider1.change(
|
|
|
|
| 494 |
fn=segment_with_coords,
|
| 495 |
inputs=[image_input, model_dropdown2, coord_input],
|
| 496 |
outputs=[cell_count_output2, overlay_output2, info_output2, viability_section2]
|
| 497 |
+
).then( # Chain the viability assessment after segmentation
|
| 498 |
+
fn=update_viability_assessment,
|
| 499 |
+
inputs=[blue_threshold_slider2],
|
| 500 |
+
outputs=[viability_overlay2, live_count_output2, dead_count_output2, viability_info2]
|
| 501 |
)
|
| 502 |
|
| 503 |
blue_threshold_slider2.change(
|