1313import shutil
1414import logging
1515import sys
16+ import math
17+ import scipy .ndimage
1618
1719#################################
1820#
8890CELLPOSE_DOCKERS = {'v2' : ["cellprofiler/runcellpose_no_pretrained:2.3.2" ,
8991 "cellprofiler/runcellpose_with_pretrained:2.3.2" ,
9092 "cellprofiler/runcellpose_with_pretrained:2.2" ],
91- 'v3' : ["biocontainers /cellpose:3.1.0_cv1 " ], #TODO
92- 'v4' : ["docker4 " ]} #TODO
93+ 'v3' : ["erinweisbart /cellpose:3.1.1.2 " ], #TODO
94+ 'v4' : ["erinweisbart/cellpose:4.0.5 " ]} #TODO
9395
9496"Detection mode"
9597MODEL_NAMES = {'v2' :['cyto' ,'nuclei' ,'tissuenet' ,'livecell' , 'cyto2' , 'general' ,
9698 'CP' , 'CPx' , 'TN1' , 'TN2' , 'TN3' , 'LC1' , 'LC2' , 'LC3' , 'LC4' , 'custom' ],
9799 'v3' :[ "cyto3" , "nuclei" , "cyto2_cp3" , "tissuenet_cp3" , "livecell_cp3" , "yeast_PhC_cp3" ,
98- "yeast_BF_cp3" , "bact_phase_cp3" , "bact_fluor_cp3" , "deepbacs_cp3" , "cyto2" , "cyto" ],
99- 'v4' :['cpsam' ]}
100+ "yeast_BF_cp3" , "bact_phase_cp3" , "bact_fluor_cp3" , "deepbacs_cp3" , "cyto2" , "cyto" , "custom" ],
101+ 'v4' :['cpsam' , 'custom' ]}
100102
101103DENOISER_NAMES = ['denoise_cyto3' , 'deblur_cyto3' , 'upsample_cyto3' ,
102104 'denoise_nuclei' , 'deblur_nuclei' , 'upsample_nuclei' ]
@@ -493,10 +495,13 @@ def visible_settings(self):
493495
494496 if self .cellpose_version .value == 'v2' :
495497 vis_settings += [self .mode_v2 ]
498+ self .mode = self .mode_v2
496499 elif self .cellpose_version .value == 'v3' :
497500 vis_settings += [self .mode_v3 ]
501+ self .mode = self .mode_v3
498502 elif self .cellpose_version .value == 'v4' :
499503 vis_settings += [self .mode_v4 ]
504+ self .mode = self .mode_v4
500505
501506 vis_settings += [self .x_name ]
502507
@@ -805,7 +810,7 @@ def run(self, workspace):
805810 cmd += ['/data/model/' + model_file ]
806811 if self .cellpose_version .value == 'v3' :
807812 if self .denoise .value :
808- cmd += ['--denoise ' , self .denoise_type .value ]
813+ cmd += ['--restore_type ' , self .denoise_type .value ]
809814 if self .cellpose_version .value in ['v2' ,'v3' ]:
810815 cmd += ['--chan' , str (channels [0 ]), '--chan2' , str (channels [1 ]), '--diameter' , str (diam )]
811816 if self .cellpose_version .value in ['v4' ]:
@@ -826,9 +831,10 @@ def run(self, workspace):
826831 try :
827832 subprocess .run (cmd , text = True )
828833 cellpose_output = numpy .load (os .path .join (temp_img_dir , unique_name + "_seg.npy" ), allow_pickle = True ).item ()
829-
830834 y_data = cellpose_output ["masks" ]
831835 flows = cellpose_output ["flows" ]
836+ if self .denoise .value :
837+ img_restore = cellpose_output ["restore" ] #TODO don't think this is correct for retrieving image for plotting
832838 finally :
833839 # Delete the temporary files
834840 try :
@@ -843,10 +849,11 @@ def run(self, workspace):
843849 y .parent_image = x .parent_image
844850 objects = workspace .object_set
845851 objects .add_objects (y , y_name )
852+ object_count = y .count
846853
847854 if self .denoise .value and self .show_window :
848855 # Need to remove unnecessary extra axes
849- denoised_image = numpy .squeeze (input_data )
856+ denoised_image = numpy .squeeze (img_restore )
850857 if "upsample" in self .denoise_type .value :
851858 denoised_image = skimage .transform .resize (
852859 denoised_image , x_data .shape )
@@ -888,20 +895,53 @@ def run(self, workspace):
888895 workspace .display_data .y_data = y_data
889896 workspace .display_data .dimensions = dimensions
890897
898+ workspace .display_data .primary_labels = y .segmented
899+
900+ workspace .display_data .statistics = []
901+ statistics = workspace .display_data .statistics
902+ statistics .append (["# of accepted objects" , "%d" % object_count ])
903+
904+ if object_count > 0 :
905+ areas = y .areas
906+ areas .sort ()
907+ low_diameter = (
908+ math .sqrt (float (areas [object_count // 10 ]) / numpy .pi ) * 2
909+ )
910+ median_diameter = (
911+ math .sqrt (float (areas [object_count // 2 ]) / numpy .pi ) * 2
912+ )
913+ high_diameter = (
914+ math .sqrt (float (areas [object_count * 9 // 10 ]) / numpy .pi ) * 2
915+ )
916+ statistics .append (
917+ ["10th pctile diameter" , "%.1f pixels" % low_diameter ]
918+ )
919+ statistics .append (["Median diameter" , "%.1f pixels" % median_diameter ])
920+ statistics .append (
921+ ["90th pctile diameter" , "%.1f pixels" % high_diameter ]
922+ )
923+ object_area = numpy .sum (areas )
924+ total_area = numpy .product (y_data .shape [:2 ])
925+ statistics .append (
926+ [
927+ "Area covered by objects" ,
928+ "%.1f %%" % (100.0 * float (object_area ) / float (total_area )),
929+ ]
930+ )
931+
891932 def display (self , workspace , figure ):
892- if self .save_probabilities .value :
893- layout = (2 , 2 )
933+ if self .save_probabilities .value or self . denoise . value :
934+ layout = (3 , 2 )
894935 else :
895- layout = (2 , 1 )
896-
897- figure .set_subplots (
898- dimensions = workspace .display_data .dimensions , subplots = layout
899- )
936+ layout = (2 , 2 )
900937
938+ figure .set_subplots (subplots = layout )
939+
940+ title = "Input image, cycle #%d" % (workspace .measurements .image_number ,)
901941 figure .subplot_imshow (
902942 colormap = "gray" ,
903943 image = workspace .display_data .x_data ,
904- title = "Input Image" ,
944+ title = title ,
905945 x = 0 ,
906946 y = 0 ,
907947 )
@@ -913,13 +953,39 @@ def display(self, workspace, figure):
913953 x = 1 ,
914954 y = 0 ,
915955 )
956+
957+ cplabels = [
958+ dict (name = self .y_name .value , labels = [workspace .display_data .primary_labels ]),
959+ ]
960+
961+ title = "%s outlines" % self .y_name .value
962+ figure .subplot_imshow_grayscale (
963+ 0 , 1 , workspace .display_data .x_data , title , cplabels = cplabels , sharexy = figure .subplot (0 , 0 ),
964+ )
965+
966+ figure .subplot_table (
967+ 1 ,
968+ 1 ,
969+ [[x [1 ]] for x in workspace .display_data .statistics ],
970+ row_labels = [x [0 ] for x in workspace .display_data .statistics ],
971+ )
972+
916973 if self .save_probabilities .value :
917974 figure .subplot_imshow (
918975 colormap = "gray" ,
919976 image = workspace .display_data .probabilities ,
920977 sharexy = figure .subplot (0 , 0 ),
921978 title = self .probabilities_name .value ,
922- x = 0 ,
979+ x = 2 ,
980+ y = 0 ,
981+ )
982+ if self .denoise .value :
983+ figure .subplot_imshow (
984+ colormap = "gray" ,
985+ image = workspace .display_data .recon ,
986+ sharexy = figure .subplot (0 , 0 ),
987+ title = self .denoise .value ,
988+ x = 2 ,
923989 y = 1 ,
924990 )
925991
0 commit comments