LiangLabUMB commited on
Commit
f99ecba
·
verified ·
1 Parent(s): 53c5253

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +170 -1
app.py CHANGED
@@ -447,7 +447,7 @@ with gr.Blocks(
447
  masks_state = gr.State(value=None)
448
  image_state = gr.State(value=None)
449
 
450
- with gr.Tab("Cell Quantification"):
451
  gr.Markdown("Run segmentation")
452
 
453
  with gr.Row():
@@ -616,6 +616,175 @@ with gr.Blocks(
616
  inputs=[blue_threshold1, masks_state, image_state],
617
  outputs=[viability_overlay1, live_count_output1, dead_count_output1, viability_percent_output1, viability_info1]
618
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
619
 
620
  # Instructions
621
  with gr.Accordion("Instructions", open=False):
 
447
  masks_state = gr.State(value=None)
448
  image_state = gr.State(value=None)
449
 
450
+ with gr.Tab("Tab 1"):
451
  gr.Markdown("Run segmentation")
452
 
453
  with gr.Row():
 
616
  inputs=[blue_threshold1, masks_state, image_state],
617
  outputs=[viability_overlay1, live_count_output1, dead_count_output1, viability_percent_output1, viability_info1]
618
  )
619
+ with gr.Tab("Tab 2"):
620
+ gr.Markdown("Run segmentation")
621
+
622
+ with gr.Row():
623
+ with gr.Column():
624
+ img_input2 = gr.Image(
625
+ type="pil",
626
+ label="Microscopy image",
627
+ image_mode="RGB",
628
+ height=512
629
+ )
630
+
631
+ model_dropdown2 = gr.Dropdown(
632
+ choices=list(MODEL_OPTIONS.keys()),
633
+ label="Select Model",
634
+ value="Hemocytometer Model"
635
+ )
636
+
637
+ min_size_slider2 = gr.Slider(
638
+ minimum=0,
639
+ maximum=500,
640
+ value=0,
641
+ step=10,
642
+ label="Minimum Cell Size (pixels). Leave at zero for automated recommendation",
643
+ )
644
+
645
+ max_size_slider2 = gr.Slider(
646
+ minimum=0,
647
+ maximum=10000,
648
+ value=10000,
649
+ step=10,
650
+ label="Maximum Cell Size (pixels)",
651
+ )
652
+
653
+ # Stereological counting option
654
+ gr.Markdown("### Stereological Counting")
655
+ use_stereology_checkbox2 = gr.Checkbox(
656
+ label="Enable Stereological Counting",
657
+ value=False,
658
+ info="Use unbiased stereological rules for cell counting"
659
+ )
660
+
661
+ # Stereological controls (initially hidden)
662
+ with gr.Group(visible=False) as stereology_controls:
663
+ gr.Markdown("""
664
+ **Stereological Counting Rules:**
665
+ - Cells touching LEFT or TOP exclusion zones are EXCLUDED
666
+ - Cells touching RIGHT or BOTTOM edges are INCLUDED
667
+ - This provides unbiased counting for quantification
668
+ """)
669
+
670
+ exclusion_preview2 = gr.Image(
671
+ type="pil",
672
+ label="Exclusion Zone Preview (Red = Excluded)",
673
+ height=500
674
+ )
675
+
676
+ left_exclusion_slider2 = gr.Slider(
677
+ minimum=0,
678
+ maximum=50,
679
+ value=10,
680
+ step=1,
681
+ label="Left Exclusion Width (%)",
682
+ info="Width of left exclusion zone"
683
+ )
684
+
685
+ top_exclusion_slider2 = gr.Slider(
686
+ minimum=0,
687
+ maximum=50,
688
+ value=10,
689
+ step=1,
690
+ label="Top Exclusion Width (%)",
691
+ info="Width of top exclusion zone"
692
+ )
693
+
694
+ segment_btn2 = gr.Button("🔬 Run Segmentation", variant="primary", size="lg")
695
+
696
+ with gr.Column():
697
+ cell_count_output2 = gr.Number(label="Total Cells Detected", precision=0)
698
+ confluency_output2 = gr.Number(label="Confluency (%)", precision=1)
699
+ overlay_output2 = gr.Image(type="pil", label="Segmentation Result")
700
+ info_output2 = gr.Textbox(label="Processing Info", lines=4)
701
+
702
+ # Viability Assessment Section
703
+ with gr.Group(visible=False) as viability_section1:
704
+ gr.Markdown("### Viability Assessment (Trypan Blue)")
705
+ gr.Markdown("Adjust the threshold to classify cells as live (green) or dead (red).")
706
+
707
+ with gr.Row():
708
+ with gr.Column():
709
+ blue_threshold2 = gr.Slider(
710
+ minimum=0,
711
+ maximum=100,
712
+ value=25,
713
+ step=1,
714
+ label="Blue Threshold (%)",
715
+ info="Higher values = more selective for blue cells"
716
+ )
717
+
718
+ with gr.Column():
719
+ live_count_output2 = gr.Number(label="Live Cells (Green)", precision=0)
720
+ dead_count_output2 = gr.Number(label="Dead Cells (Red)", precision=0)
721
+
722
+ viability_overlay2 = gr.Image(type="pil", label="Viability Assessment (Green=Live, Red=Dead)")
723
+ viability_percent_output2 = gr.Number(label="Viability (%)", precision=1)
724
+ viability_info2 = gr.Textbox(label="Analysis Results", lines=5)
725
+
726
+ # Event handlers
727
+
728
+ # Toggle stereological controls visibility
729
+ use_stereology_checkbox2.change(
730
+ fn=toggle_stereological_mode,
731
+ inputs=[use_stereology_checkbox],
732
+ outputs=[stereology_controls]
733
+ )
734
+
735
+ # Update exclusion preview when image is uploaded or sliders change
736
+ img_input2.change(
737
+ fn=update_exclusion_preview,
738
+ inputs=[img_input2, left_exclusion_slider2, top_exclusion_slider2],
739
+ outputs=[exclusion_preview]
740
+ )
741
+
742
+ left_exclusion_slider2.change(
743
+ fn=update_exclusion_preview,
744
+ inputs=[img_input2, left_exclusion_slider2, top_exclusion_slider2],
745
+ outputs=[exclusion_preview]
746
+ )
747
+
748
+ top_exclusion_slider2.change(
749
+ fn=update_exclusion_preview,
750
+ inputs=[img_input2, left_exclusion_slider2, top_exclusion_slider2],
751
+ outputs=[exclusion_preview]
752
+ )
753
+
754
+ # Run segmentation
755
+ segment_btn2.click(
756
+ fn=run_segmentation,
757
+ inputs=[
758
+ img_input,
759
+ model_dropdown2,
760
+ min_size_slider2,
761
+ max_size_slider2,
762
+ use_stereology_checkbox2,
763
+ left_exclusion_slider2,
764
+ top_exclusion_slider2
765
+ ],
766
+ outputs=[
767
+ cell_count_output2,
768
+ overlay_output2,
769
+ info_output2,
770
+ viability_section2,
771
+ masks_state,
772
+ image_state,
773
+ confluency_output2,
774
+ min_size_slider2
775
+ ]
776
+ ).then( # Chain the initial viability assessment after segmentation
777
+ fn=update_viability_realtime,
778
+ inputs=[blue_threshold2, masks_state, image_state],
779
+ outputs=[viability_overlay2, live_count_output2, dead_count_output2, viability_percent_output2, viability_info2]
780
+ )
781
+
782
+ # Slider changes update viability in real-time
783
+ blue_threshold2.change(
784
+ fn=update_viability_realtime,
785
+ inputs=[blue_threshold2, masks_state, image_state],
786
+ outputs=[viability_overlay2, live_count_output2, dead_count_output2, viability_percent_output2, viability_info2]
787
+ )
788
 
789
  # Instructions
790
  with gr.Accordion("Instructions", open=False):