LiangLabUMB commited on
Commit
1a20de7
·
verified ·
1 Parent(s): ef1b15c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +509 -1
app.py CHANGED
@@ -755,7 +755,7 @@ with gr.Blocks(
755
  segment_btn2.click(
756
  fn=run_segmentation,
757
  inputs=[
758
- img_input,
759
  model_dropdown2,
760
  min_size_slider2,
761
  max_size_slider2,
@@ -786,6 +786,514 @@ with gr.Blocks(
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):
791
  gr.Markdown("""
 
755
  segment_btn2.click(
756
  fn=run_segmentation,
757
  inputs=[
758
+ img_input2,
759
  model_dropdown2,
760
  min_size_slider2,
761
  max_size_slider2,
 
786
  outputs=[viability_overlay2, live_count_output2, dead_count_output2, viability_percent_output2, viability_info2]
787
  )
788
 
789
+ with gr.Tab("Tab 3"):
790
+ gr.Markdown("Run segmentation")
791
+
792
+ with gr.Row():
793
+ with gr.Column():
794
+ img_input3 = gr.Image(
795
+ type="pil",
796
+ label="Microscopy image",
797
+ image_mode="RGB",
798
+ height=512
799
+ )
800
+
801
+ model_dropdown3 = gr.Dropdown(
802
+ choices=list(MODEL_OPTIONS.keys()),
803
+ label="Select Model",
804
+ value="Hemocytometer Model"
805
+ )
806
+
807
+ min_size_slider3 = gr.Slider(
808
+ minimum=0,
809
+ maximum=500,
810
+ value=0,
811
+ step=10,
812
+ label="Minimum Cell Size (pixels). Leave at zero for automated recommendation",
813
+ )
814
+
815
+ max_size_slider3 = gr.Slider(
816
+ minimum=0,
817
+ maximum=10000,
818
+ value=10000,
819
+ step=10,
820
+ label="Maximum Cell Size (pixels)",
821
+ )
822
+
823
+ # Stereological counting option
824
+ gr.Markdown("### Stereological Counting")
825
+ use_stereology_checkbox3 = gr.Checkbox(
826
+ label="Enable Stereological Counting",
827
+ value=False,
828
+ info="Use unbiased stereological rules for cell counting"
829
+ )
830
+
831
+ # Stereological controls (initially hidden)
832
+ with gr.Group(visible=False) as stereology_controls3:
833
+ gr.Markdown("""
834
+ **Stereological Counting Rules:**
835
+ - Cells touching LEFT or TOP exclusion zones are EXCLUDED
836
+ - Cells touching RIGHT or BOTTOM edges are INCLUDED
837
+ - This provides unbiased counting for quantification
838
+ """)
839
+
840
+ exclusion_preview3 = gr.Image(
841
+ type="pil",
842
+ label="Exclusion Zone Preview (Red = Excluded)",
843
+ height=500
844
+ )
845
+
846
+ left_exclusion_slider3 = gr.Slider(
847
+ minimum=0,
848
+ maximum=50,
849
+ value=10,
850
+ step=1,
851
+ label="Left Exclusion Width (%)",
852
+ info="Width of left exclusion zone"
853
+ )
854
+
855
+ top_exclusion_slider3 = gr.Slider(
856
+ minimum=0,
857
+ maximum=50,
858
+ value=10,
859
+ step=1,
860
+ label="Top Exclusion Width (%)",
861
+ info="Width of top exclusion zone"
862
+ )
863
+
864
+ segment_btn3 = gr.Button("🔬 Run Segmentation", variant="primary", size="lg")
865
+
866
+ with gr.Column():
867
+ cell_count_output3 = gr.Number(label="Total Cells Detected", precision=0)
868
+ confluency_output3 = gr.Number(label="Confluency (%)", precision=1)
869
+ overlay_output3 = gr.Image(type="pil", label="Segmentation Result")
870
+ info_output3 = gr.Textbox(label="Processing Info", lines=4)
871
+
872
+ # Viability Assessment Section
873
+ with gr.Group(visible=False) as viability_section3:
874
+ gr.Markdown("### Viability Assessment (Trypan Blue)")
875
+ gr.Markdown("Adjust the threshold to classify cells as live (green) or dead (red).")
876
+
877
+ with gr.Row():
878
+ with gr.Column():
879
+ blue_threshold3 = gr.Slider(
880
+ minimum=0,
881
+ maximum=100,
882
+ value=25,
883
+ step=1,
884
+ label="Blue Threshold (%)",
885
+ info="Higher values = more selective for blue cells"
886
+ )
887
+
888
+ with gr.Column():
889
+ live_count_output3 = gr.Number(label="Live Cells (Green)", precision=0)
890
+ dead_count_output3 = gr.Number(label="Dead Cells (Red)", precision=0)
891
+
892
+ viability_overlay3 = gr.Image(type="pil", label="Viability Assessment (Green=Live, Red=Dead)")
893
+ viability_percent_output3 = gr.Number(label="Viability (%)", precision=1)
894
+ viability_info3 = gr.Textbox(label="Analysis Results", lines=5)
895
+
896
+ # Event handlers
897
+
898
+ # Toggle stereological controls visibility
899
+ use_stereology_checkbox3.change(
900
+ fn=toggle_stereological_mode,
901
+ inputs=[use_stereology_checkbox3],
902
+ outputs=[stereology_controls3]
903
+ )
904
+
905
+ # Update exclusion preview when image is uploaded or sliders change
906
+ img_input3.change(
907
+ fn=update_exclusion_preview,
908
+ inputs=[img_input3, left_exclusion_slider3, top_exclusion_slider3],
909
+ outputs=[exclusion_preview3]
910
+ )
911
+
912
+ left_exclusion_slider3.change(
913
+ fn=update_exclusion_preview,
914
+ inputs=[img_input3, left_exclusion_slider3, top_exclusion_slider3],
915
+ outputs=[exclusion_preview3]
916
+ )
917
+
918
+ top_exclusion_slider3.change(
919
+ fn=update_exclusion_preview,
920
+ inputs=[img_input3, left_exclusion_slider3, top_exclusion_slider3],
921
+ outputs=[exclusion_preview3]
922
+ )
923
+
924
+ # Run segmentation
925
+ segment_btn3.click(
926
+ fn=run_segmentation,
927
+ inputs=[
928
+ img_input3,
929
+ model_dropdown3,
930
+ min_size_slider3,
931
+ max_size_slider3,
932
+ use_stereology_checkbox3,
933
+ left_exclusion_slider3,
934
+ top_exclusion_slider3
935
+ ],
936
+ outputs=[
937
+ cell_count_output3,
938
+ overlay_output3,
939
+ info_output3,
940
+ viability_section3,
941
+ masks_state,
942
+ image_state,
943
+ confluency_output3,
944
+ min_size_slider3
945
+ ]
946
+ ).then( # Chain the initial viability assessment after segmentation
947
+ fn=update_viability_realtime,
948
+ inputs=[blue_threshold3, masks_state, image_state],
949
+ outputs=[viability_overlay3, live_count_output3, dead_count_output3, viability_percent_output3, viability_info3]
950
+ )
951
+
952
+ # Slider changes update viability in real-time
953
+ blue_threshold3.change(
954
+ fn=update_viability_realtime,
955
+ inputs=[blue_threshold3, masks_state, image_state],
956
+ outputs=[viability_overlay3, live_count_output3, dead_count_output3, viability_percent_output3, viability_info3]
957
+ )
958
+ with gr.Tab("Tab 3"):
959
+ gr.Markdown("Run segmentation")
960
+
961
+ with gr.Row():
962
+ with gr.Column():
963
+ img_input3 = gr.Image(
964
+ type="pil",
965
+ label="Microscopy image",
966
+ image_mode="RGB",
967
+ height=512
968
+ )
969
+
970
+ model_dropdown3 = gr.Dropdown(
971
+ choices=list(MODEL_OPTIONS.keys()),
972
+ label="Select Model",
973
+ value="Hemocytometer Model"
974
+ )
975
+
976
+ min_size_slider3 = gr.Slider(
977
+ minimum=0,
978
+ maximum=500,
979
+ value=0,
980
+ step=10,
981
+ label="Minimum Cell Size (pixels). Leave at zero for automated recommendation",
982
+ )
983
+
984
+ max_size_slider3 = gr.Slider(
985
+ minimum=0,
986
+ maximum=10000,
987
+ value=10000,
988
+ step=10,
989
+ label="Maximum Cell Size (pixels)",
990
+ )
991
+
992
+ # Stereological counting option
993
+ gr.Markdown("### Stereological Counting")
994
+ use_stereology_checkbox3 = gr.Checkbox(
995
+ label="Enable Stereological Counting",
996
+ value=False,
997
+ info="Use unbiased stereological rules for cell counting"
998
+ )
999
+
1000
+ # Stereological controls (initially hidden)
1001
+ with gr.Group(visible=False) as stereology_controls3:
1002
+ gr.Markdown("""
1003
+ **Stereological Counting Rules:**
1004
+ - Cells touching LEFT or TOP exclusion zones are EXCLUDED
1005
+ - Cells touching RIGHT or BOTTOM edges are INCLUDED
1006
+ - This provides unbiased counting for quantification
1007
+ """)
1008
+
1009
+ exclusion_preview3 = gr.Image(
1010
+ type="pil",
1011
+ label="Exclusion Zone Preview (Red = Excluded)",
1012
+ height=500
1013
+ )
1014
+
1015
+ left_exclusion_slider3 = gr.Slider(
1016
+ minimum=0,
1017
+ maximum=50,
1018
+ value=10,
1019
+ step=1,
1020
+ label="Left Exclusion Width (%)",
1021
+ info="Width of left exclusion zone"
1022
+ )
1023
+
1024
+ top_exclusion_slider3 = gr.Slider(
1025
+ minimum=0,
1026
+ maximum=50,
1027
+ value=10,
1028
+ step=1,
1029
+ label="Top Exclusion Width (%)",
1030
+ info="Width of top exclusion zone"
1031
+ )
1032
+
1033
+ segment_btn3 = gr.Button("🔬 Run Segmentation", variant="primary", size="lg")
1034
+
1035
+ with gr.Column():
1036
+ cell_count_output3 = gr.Number(label="Total Cells Detected", precision=0)
1037
+ confluency_output3 = gr.Number(label="Confluency (%)", precision=1)
1038
+ overlay_output3 = gr.Image(type="pil", label="Segmentation Result")
1039
+ info_output3 = gr.Textbox(label="Processing Info", lines=4)
1040
+
1041
+ # Viability Assessment Section
1042
+ with gr.Group(visible=False) as viability_section3:
1043
+ gr.Markdown("### Viability Assessment (Trypan Blue)")
1044
+ gr.Markdown("Adjust the threshold to classify cells as live (green) or dead (red).")
1045
+
1046
+ with gr.Row():
1047
+ with gr.Column():
1048
+ blue_threshold3 = gr.Slider(
1049
+ minimum=0,
1050
+ maximum=100,
1051
+ value=25,
1052
+ step=1,
1053
+ label="Blue Threshold (%)",
1054
+ info="Higher values = more selective for blue cells"
1055
+ )
1056
+
1057
+ with gr.Column():
1058
+ live_count_output3 = gr.Number(label="Live Cells (Green)", precision=0)
1059
+ dead_count_output3 = gr.Number(label="Dead Cells (Red)", precision=0)
1060
+
1061
+ viability_overlay3 = gr.Image(type="pil", label="Viability Assessment (Green=Live, Red=Dead)")
1062
+ viability_percent_output3 = gr.Number(label="Viability (%)", precision=1)
1063
+ viability_info3 = gr.Textbox(label="Analysis Results", lines=5)
1064
+
1065
+ # Event handlers
1066
+
1067
+ # Toggle stereological controls visibility
1068
+ use_stereology_checkbox3.change(
1069
+ fn=toggle_stereological_mode,
1070
+ inputs=[use_stereology_checkbox3],
1071
+ outputs=[stereology_controls3]
1072
+ )
1073
+
1074
+ # Update exclusion preview when image is uploaded or sliders change
1075
+ img_input3.change(
1076
+ fn=update_exclusion_preview,
1077
+ inputs=[img_input3, left_exclusion_slider3, top_exclusion_slider3],
1078
+ outputs=[exclusion_preview3]
1079
+ )
1080
+
1081
+ left_exclusion_slider3.change(
1082
+ fn=update_exclusion_preview,
1083
+ inputs=[img_input3, left_exclusion_slider3, top_exclusion_slider3],
1084
+ outputs=[exclusion_preview3]
1085
+ )
1086
+
1087
+ top_exclusion_slider3.change(
1088
+ fn=update_exclusion_preview,
1089
+ inputs=[img_input3, left_exclusion_slider3, top_exclusion_slider3],
1090
+ outputs=[exclusion_preview3]
1091
+ )
1092
+
1093
+ # Run segmentation
1094
+ segment_btn3.click(
1095
+ fn=run_segmentation,
1096
+ inputs=[
1097
+ img_input3,
1098
+ model_dropdown3,
1099
+ min_size_slider3,
1100
+ max_size_slider3,
1101
+ use_stereology_checkbox3,
1102
+ left_exclusion_slider3,
1103
+ top_exclusion_slider3
1104
+ ],
1105
+ outputs=[
1106
+ cell_count_output3,
1107
+ overlay_output3,
1108
+ info_output3,
1109
+ viability_section3,
1110
+ masks_state,
1111
+ image_state,
1112
+ confluency_output3,
1113
+ min_size_slider3
1114
+ ]
1115
+ ).then( # Chain the initial viability assessment after segmentation
1116
+ fn=update_viability_realtime,
1117
+ inputs=[blue_threshold3, masks_state, image_state],
1118
+ outputs=[viability_overlay3, live_count_output3, dead_count_output3, viability_percent_output3, viability_info3]
1119
+ )
1120
+
1121
+ # Slider changes update viability in real-time
1122
+ blue_threshold3.change(
1123
+ fn=update_viability_realtime,
1124
+ inputs=[blue_threshold3, masks_state, image_state],
1125
+ outputs=[viability_overlay3, live_count_output3, dead_count_output3, viability_percent_output3, viability_info3]
1126
+ )
1127
+ with gr.Tab("Tab 4"):
1128
+ gr.Markdown("Run segmentation")
1129
+
1130
+ with gr.Row():
1131
+ with gr.Column():
1132
+ img_input4 = gr.Image(
1133
+ type="pil",
1134
+ label="Microscopy image",
1135
+ image_mode="RGB",
1136
+ height=512
1137
+ )
1138
+
1139
+ model_dropdown4 = gr.Dropdown(
1140
+ choices=list(MODEL_OPTIONS.keys()),
1141
+ label="Select Model",
1142
+ value="Hemocytometer Model"
1143
+ )
1144
+
1145
+ min_size_slider4 = gr.Slider(
1146
+ minimum=0,
1147
+ maximum=500,
1148
+ value=0,
1149
+ step=10,
1150
+ label="Minimum Cell Size (pixels). Leave at zero for automated recommendation",
1151
+ )
1152
+
1153
+ max_size_slider4 = gr.Slider(
1154
+ minimum=0,
1155
+ maximum=10000,
1156
+ value=10000,
1157
+ step=10,
1158
+ label="Maximum Cell Size (pixels)",
1159
+ )
1160
+
1161
+ # Stereological counting option
1162
+ gr.Markdown("### Stereological Counting")
1163
+ use_stereology_checkbox4 = gr.Checkbox(
1164
+ label="Enable Stereological Counting",
1165
+ value=False,
1166
+ info="Use unbiased stereological rules for cell counting"
1167
+ )
1168
+
1169
+ # Stereological controls (initially hidden)
1170
+ with gr.Group(visible=False) as stereology_controls4:
1171
+ gr.Markdown("""
1172
+ **Stereological Counting Rules:**
1173
+ - Cells touching LEFT or TOP exclusion zones are EXCLUDED
1174
+ - Cells touching RIGHT or BOTTOM edges are INCLUDED
1175
+ - This provides unbiased counting for quantification
1176
+ """)
1177
+
1178
+ exclusion_preview4 = gr.Image(
1179
+ type="pil",
1180
+ label="Exclusion Zone Preview (Red = Excluded)",
1181
+ height=500
1182
+ )
1183
+
1184
+ left_exclusion_slider4 = gr.Slider(
1185
+ minimum=0,
1186
+ maximum=50,
1187
+ value=10,
1188
+ step=1,
1189
+ label="Left Exclusion Width (%)",
1190
+ info="Width of left exclusion zone"
1191
+ )
1192
+
1193
+ top_exclusion_slider4 = gr.Slider(
1194
+ minimum=0,
1195
+ maximum=50,
1196
+ value=10,
1197
+ step=1,
1198
+ label="Top Exclusion Width (%)",
1199
+ info="Width of top exclusion zone"
1200
+ )
1201
+
1202
+ segment_btn4 = gr.Button("🔬 Run Segmentation", variant="primary", size="lg")
1203
+
1204
+ with gr.Column():
1205
+ cell_count_output4 = gr.Number(label="Total Cells Detected", precision=0)
1206
+ confluency_output4 = gr.Number(label="Confluency (%)", precision=1)
1207
+ overlay_output4 = gr.Image(type="pil", label="Segmentation Result")
1208
+ info_output4 = gr.Textbox(label="Processing Info", lines=4)
1209
+
1210
+ # Viability Assessment Section
1211
+ with gr.Group(visible=False) as viability_section4:
1212
+ gr.Markdown("### Viability Assessment (Trypan Blue)")
1213
+ gr.Markdown("Adjust the threshold to classify cells as live (green) or dead (red).")
1214
+
1215
+ with gr.Row():
1216
+ with gr.Column():
1217
+ blue_threshold4 = gr.Slider(
1218
+ minimum=0,
1219
+ maximum=100,
1220
+ value=25,
1221
+ step=1,
1222
+ label="Blue Threshold (%)",
1223
+ info="Higher values = more selective for blue cells"
1224
+ )
1225
+
1226
+ with gr.Column():
1227
+ live_count_output4 = gr.Number(label="Live Cells (Green)", precision=0)
1228
+ dead_count_output4 = gr.Number(label="Dead Cells (Red)", precision=0)
1229
+
1230
+ viability_overlay4 = gr.Image(type="pil", label="Viability Assessment (Green=Live, Red=Dead)")
1231
+ viability_percent_output4 = gr.Number(label="Viability (%)", precision=1)
1232
+ viability_info4 = gr.Textbox(label="Analysis Results", lines=5)
1233
+
1234
+ # Event handlers
1235
+
1236
+ # Toggle stereological controls visibility
1237
+ use_stereology_checkbox4.change(
1238
+ fn=toggle_stereological_mode,
1239
+ inputs=[use_stereology_checkbox4],
1240
+ outputs=[stereology_controls4]
1241
+ )
1242
+
1243
+ # Update exclusion preview when image is uploaded or sliders change
1244
+ img_input4.change(
1245
+ fn=update_exclusion_preview,
1246
+ inputs=[img_input4, left_exclusion_slider4, top_exclusion_slider4],
1247
+ outputs=[exclusion_preview4]
1248
+ )
1249
+
1250
+ left_exclusion_slider4.change(
1251
+ fn=update_exclusion_preview,
1252
+ inputs=[img_input4, left_exclusion_slider4, top_exclusion_slider4],
1253
+ outputs=[exclusion_preview4]
1254
+ )
1255
+
1256
+ top_exclusion_slider4.change(
1257
+ fn=update_exclusion_preview,
1258
+ inputs=[img_input4, left_exclusion_slider4, top_exclusion_slider4],
1259
+ outputs=[exclusion_preview4]
1260
+ )
1261
+
1262
+ # Run segmentation
1263
+ segment_btn4.click(
1264
+ fn=run_segmentation,
1265
+ inputs=[
1266
+ img_input4,
1267
+ model_dropdown4,
1268
+ min_size_slider4,
1269
+ max_size_slider4,
1270
+ use_stereology_checkbox4,
1271
+ left_exclusion_slider4,
1272
+ top_exclusion_slider4
1273
+ ],
1274
+ outputs=[
1275
+ cell_count_output4,
1276
+ overlay_output4,
1277
+ info_output4,
1278
+ viability_section4,
1279
+ masks_state,
1280
+ image_state,
1281
+ confluency_output4,
1282
+ min_size_slider4
1283
+ ]
1284
+ ).then( # Chain the initial viability assessment after segmentation
1285
+ fn=update_viability_realtime,
1286
+ inputs=[blue_threshold4, masks_state, image_state],
1287
+ outputs=[viability_overlay4, live_count_output4, dead_count_output4, viability_percent_output4, viability_info4]
1288
+ )
1289
+
1290
+ # Slider changes update viability in real-time
1291
+ blue_threshold3.change(
1292
+ fn=update_viability_realtime,
1293
+ inputs=[blue_threshold4, masks_state, image_state],
1294
+ outputs=[viability_overlay4, live_count_output4, dead_count_output4, viability_percent_output4, viability_info4]
1295
+ )
1296
+
1297
  # Instructions
1298
  with gr.Accordion("Instructions", open=False):
1299
  gr.Markdown("""