mmrech commited on
Commit
fbc936c
Β·
1 Parent(s): cb8ab86

Add batch/sequence processing: view segmentation sequence for multiple images from same subject

Browse files
Files changed (1) hide show
  1. app.py +151 -53
app.py CHANGED
@@ -264,21 +264,57 @@ def load_demo_file():
264
  else:
265
  return None, "⚠️ Demo file not found. Please upload a medical image file (DICOM, PNG, or JPG)."
266
 
267
- def process_with_status(dicom_file, prompt_text, modality, window_type):
268
  """Wrapper function to update status during processing."""
269
  if model is None or processor is None:
270
  return None, "❌ Error: Model not loaded."
271
 
272
- if dicom_file is None:
273
  return None, "⚠️ Please upload a medical image file (DICOM, PNG, or JPG) or load the demo file."
274
 
275
- result = process_medical_image(dicom_file, prompt_text, modality, window_type)
276
 
277
  if result is None:
278
  return None, "❌ Processing failed. Check console for error details."
279
  else:
280
  return result, "βœ… Segmentation complete!"
281
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
  with gr.Blocks() as demo:
283
  gr.Markdown("# πŸ₯ NeuroSAM 3: Medical Image Segmentation")
284
 
@@ -304,58 +340,113 @@ with gr.Blocks() as demo:
304
  - PNG/JPG - Standard image formats (works with Kaggle brain MRI datasets)
305
  """)
306
 
307
- with gr.Row():
308
- with gr.Column():
309
- file_input = gr.File(
310
- label="Upload Medical Image (DICOM .dcm, PNG, JPG)",
311
- file_types=[".dcm", ".png", ".jpg", ".jpeg"],
312
- type="filepath",
313
- value=demo_file_path
314
- )
315
-
316
- load_demo_btn = gr.Button(
317
- "πŸ“ Load Demo File",
318
- variant="secondary",
319
- size="sm",
320
- visible=bool(demo_file_path)
321
- )
322
-
323
- text_input = gr.Textbox(
324
- label="Text Prompt",
325
- value="brain",
326
- placeholder="e.g. brain, tumor, skull, eyes",
327
- info="Describe what anatomical structure or region you want to segment"
328
- )
329
-
330
  with gr.Row():
331
- modality_dropdown = gr.Dropdown(
332
- ["CT", "MRI"],
333
- label="Modality",
334
- value="MRI",
335
- info="Select the imaging modality"
336
- )
337
- window_dropdown = gr.Dropdown(
338
- ["Brain (Grey Matter)", "Bone (Skull)", "Soft Tissue (Face)"],
339
- label="Windowing Strategy (CT only)",
340
- value="Brain (Grey Matter)",
341
- info="CT windowing preset (ignored for MRI)"
342
- )
343
-
344
- submit_btn = gr.Button("Segment Structure", variant="primary", size="lg")
345
-
346
- with gr.Column():
347
- image_output = gr.Image(
348
- label="Segmentation Result",
349
- type="filepath"
350
- )
351
-
352
- gr.Markdown("### Status")
353
- status_text = gr.Textbox(
354
- label="Processing Status",
355
- value="Ready. Upload a medical image file (DICOM, PNG, or JPG) to begin.",
356
- interactive=False
357
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
 
 
359
  load_demo_btn.click(
360
  fn=load_demo_file,
361
  inputs=[],
@@ -367,6 +458,13 @@ with gr.Blocks() as demo:
367
  inputs=[file_input, text_input, modality_dropdown, window_dropdown],
368
  outputs=[image_output, status_text]
369
  )
 
 
 
 
 
 
 
370
 
371
  if __name__ == "__main__":
372
  demo.launch()
 
264
  else:
265
  return None, "⚠️ Demo file not found. Please upload a medical image file (DICOM, PNG, or JPG)."
266
 
267
+ def process_with_status(image_file, prompt_text, modality, window_type):
268
  """Wrapper function to update status during processing."""
269
  if model is None or processor is None:
270
  return None, "❌ Error: Model not loaded."
271
 
272
+ if image_file is None:
273
  return None, "⚠️ Please upload a medical image file (DICOM, PNG, or JPG) or load the demo file."
274
 
275
+ result = process_medical_image(image_file, prompt_text, modality, window_type)
276
 
277
  if result is None:
278
  return None, "❌ Processing failed. Check console for error details."
279
  else:
280
  return result, "βœ… Segmentation complete!"
281
 
282
+ def process_sequence(image_files, prompt_text, modality, window_type):
283
+ """Process multiple images from the same subject and return gallery of results."""
284
+ if model is None or processor is None:
285
+ return [], "❌ Error: Model not loaded."
286
+
287
+ if not image_files:
288
+ return [], "⚠️ Please upload medical image files (DICOM, PNG, or JPG)."
289
+
290
+ # Handle single file or list of files
291
+ if isinstance(image_files, str):
292
+ image_files = [image_files]
293
+
294
+ results = []
295
+ status_messages = []
296
+
297
+ for idx, image_file in enumerate(image_files):
298
+ if image_file is None:
299
+ continue
300
+
301
+ status_msg = f"Processing image {idx + 1}/{len(image_files)}..."
302
+ status_messages.append(status_msg)
303
+
304
+ result = process_medical_image(image_file, prompt_text, modality, window_type)
305
+
306
+ if result:
307
+ results.append(result)
308
+ status_messages.append(f"βœ… Image {idx + 1} segmented successfully")
309
+ else:
310
+ status_messages.append(f"❌ Failed to process image {idx + 1}")
311
+
312
+ if results:
313
+ status = f"βœ… Processed {len(results)}/{len(image_files)} images successfully!\n" + "\n".join(status_messages)
314
+ return results, status
315
+ else:
316
+ return [], "❌ No images were processed successfully. Check console for error details."
317
+
318
  with gr.Blocks() as demo:
319
  gr.Markdown("# πŸ₯ NeuroSAM 3: Medical Image Segmentation")
320
 
 
340
  - PNG/JPG - Standard image formats (works with Kaggle brain MRI datasets)
341
  """)
342
 
343
+ with gr.Tabs():
344
+ with gr.Tab("Single Image"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  with gr.Row():
346
+ with gr.Column():
347
+ file_input = gr.File(
348
+ label="Upload Medical Image (DICOM .dcm, PNG, JPG)",
349
+ file_types=[".dcm", ".png", ".jpg", ".jpeg"],
350
+ type="filepath",
351
+ value=demo_file_path
352
+ )
353
+
354
+ load_demo_btn = gr.Button(
355
+ "πŸ“ Load Demo File",
356
+ variant="secondary",
357
+ size="sm",
358
+ visible=bool(demo_file_path)
359
+ )
360
+
361
+ text_input = gr.Textbox(
362
+ label="Text Prompt",
363
+ value="brain",
364
+ placeholder="e.g. brain, tumor, skull, eyes",
365
+ info="Describe what anatomical structure or region you want to segment"
366
+ )
367
+
368
+ with gr.Row():
369
+ modality_dropdown = gr.Dropdown(
370
+ ["CT", "MRI"],
371
+ label="Modality",
372
+ value="MRI",
373
+ info="Select the imaging modality"
374
+ )
375
+ window_dropdown = gr.Dropdown(
376
+ ["Brain (Grey Matter)", "Bone (Skull)", "Soft Tissue (Face)"],
377
+ label="Windowing Strategy (CT only)",
378
+ value="Brain (Grey Matter)",
379
+ info="CT windowing preset (ignored for MRI)"
380
+ )
381
+
382
+ submit_btn = gr.Button("Segment Structure", variant="primary", size="lg")
383
+
384
+ with gr.Column():
385
+ image_output = gr.Image(
386
+ label="Segmentation Result",
387
+ type="filepath"
388
+ )
389
+
390
+ gr.Markdown("### Status")
391
+ status_text = gr.Textbox(
392
+ label="Processing Status",
393
+ value="Ready. Upload a medical image file (DICOM, PNG, or JPG) to begin.",
394
+ interactive=False
395
+ )
396
+
397
+ with gr.Tab("Sequence / Batch Processing"):
398
+ gr.Markdown("**Process multiple images from the same subject to see segmentation sequence**")
399
+ with gr.Row():
400
+ with gr.Column():
401
+ files_input = gr.File(
402
+ label="Upload Multiple Images (Select multiple files)",
403
+ file_types=[".dcm", ".png", ".jpg", ".jpeg"],
404
+ file_count="multiple",
405
+ type="filepath"
406
+ )
407
+
408
+ text_input_batch = gr.Textbox(
409
+ label="Text Prompt",
410
+ value="brain",
411
+ placeholder="e.g. brain, tumor, skull, eyes",
412
+ info="Describe what anatomical structure or region you want to segment"
413
+ )
414
+
415
+ with gr.Row():
416
+ modality_dropdown_batch = gr.Dropdown(
417
+ ["CT", "MRI"],
418
+ label="Modality",
419
+ value="MRI",
420
+ info="Select the imaging modality"
421
+ )
422
+ window_dropdown_batch = gr.Dropdown(
423
+ ["Brain (Grey Matter)", "Bone (Skull)", "Soft Tissue (Face)"],
424
+ label="Windowing Strategy (CT only)",
425
+ value="Brain (Grey Matter)",
426
+ info="CT windowing preset (ignored for MRI)"
427
+ )
428
+
429
+ submit_batch_btn = gr.Button("Process Sequence", variant="primary", size="lg")
430
+
431
+ with gr.Column():
432
+ gallery_output = gr.Gallery(
433
+ label="Segmentation Sequence Results",
434
+ show_label=True,
435
+ elem_id="gallery",
436
+ columns=2,
437
+ rows=2,
438
+ height="auto"
439
+ )
440
+
441
+ gr.Markdown("### Batch Status")
442
+ status_batch_text = gr.Textbox(
443
+ label="Processing Status",
444
+ value="Ready. Upload multiple medical image files to process a sequence.",
445
+ interactive=False,
446
+ lines=5
447
+ )
448
 
449
+ # Single image processing
450
  load_demo_btn.click(
451
  fn=load_demo_file,
452
  inputs=[],
 
458
  inputs=[file_input, text_input, modality_dropdown, window_dropdown],
459
  outputs=[image_output, status_text]
460
  )
461
+
462
+ # Batch/sequence processing
463
+ submit_batch_btn.click(
464
+ fn=process_sequence,
465
+ inputs=[files_input, text_input_batch, modality_dropdown_batch, window_dropdown_batch],
466
+ outputs=[gallery_output, status_batch_text]
467
+ )
468
 
469
  if __name__ == "__main__":
470
  demo.launch()