def setForAll(self): # print(self.masksAll.currentText()) # print(self.downScaleAll.value()) # print(self.thinningAll.value()) # print(self.smoothingAll.value()) txt = self.masksAll.currentText() idx = ['ignore', 'classifier', 'watershed', 'manual'].index(txt) self.chosen_masks = [['i', 'c', 'w', 'm'][idx] for i in range(self.n_imgs)] self.down_shapes = [ self.downScaleAll.value() for i in range(self.n_imgs) ] self.thinnings = [self.thinningAll.value() for i in range(self.n_imgs)] self.smoothings = [ self.smoothingAll.value() for i in range(self.n_imgs) ] print(self.thinnings) # if os.path.exists(os.path.join(self.imageFolder,'result_segmentation',self.cond+'_morpho_params.pkl')): # utils_postprocessing.generate_final_recap(self.imageFolder, # chosen=[c!='' for c in self.chosen_masks], # saveFig=False) save_folder = os.path.join(self.imageFolder, 'result_segmentation') ioSeg.save_segmentation_params( save_folder, [os.path.split(fin)[-1] for fin in self.flist_in], self.chosen_masks, self.down_shapes, self.thinnings, self.smoothings) self.remake()
def make(self): if self.start == None: self.start = 0 if self.stop == None: len(self.flist_in) self.stop = np.clip(self.stop, 0, self.n_imgs) self.n_shown = self.stop - self.start self.showMore = False self.overview = MLModel.overview.generate_overview(self.imageFolder, saveFig=False, start=self.start, stop=self.stop, downshape=5) self.overview.show() if os.path.exists( os.path.join(self.imageFolder, 'result_segmentation', 'segmentation_params.csv')): self.flist_in, self.chosen_masks, self.down_shapes, self.thinnings, self.smoothings = ioSeg.load_segmentation_params( os.path.join(self.imageFolder, 'result_segmentation')) self.flist_in = [ os.path.join(self.imageFolder, i) for i in self.flist_in ] else: self.chosen_masks = ['c' for i in range(self.n_imgs)] self.down_shapes = [0.50 for i in range(self.n_imgs)] self.thinnings = [10 for i in range(self.n_imgs)] self.smoothings = [25 for i in range(self.n_imgs)] # if os.path.exists(os.path.join(self.imageFolder,'result_segmentation',self.cond+'_morpho_params.pkl')): # utils_postprocessing.generate_final_recap(self.imageFolder, # chosen=[c!='' for c in self.chosen_masks], # saveFig=False) save_folder = os.path.join(self.imageFolder, 'result_segmentation') ioSeg.save_segmentation_params( save_folder, [os.path.split(fin)[-1] for fin in self.flist_in], self.chosen_masks, self.down_shapes, self.thinnings, self.smoothings) mainTab = QWidget() self.createGroup1() self.createGroup2() mainTabLayout = QVBoxLayout() mainTabLayout.addWidget(self.group2) mainTabLayout.addWidget(self.group1) mainTab.setLayout(mainTabLayout) self.layout = QVBoxLayout(self) self.layout.addWidget(self.group2) self.layout.addWidget(self.group1) self.setLayout(self.layout) self.setWindowTitle('Organoids Segmentation App') QApplication.setStyle('Fusion')
def moveToPrevious(self): self.read_segmentation_params() save_folder = os.path.join(self.imageFolder, 'result_segmentation') ioSeg.save_segmentation_params( save_folder, [os.path.split(fin)[-1] for fin in self.flist_in], self.chosen_masks, self.down_shapes, self.thinnings, self.smoothings) new_start = np.clip(self.start - self.n_shown_max, 0, self.n_imgs) if self.start == new_start: QApplication.beep() print('No previous images to display!') return self.n_shown = self.start - new_start self.start = new_start self.stop = self.start + self.n_shown # np.clip(self.stop-20,20,self.n_imgs) plt.close(self.overview) self.remake()
mask = segment.smooth_mask(_rawmask, mode='manual', down_shape=down_shapes[i], smooth_order=smoothings[i]) elif chosen_masks[i] == 'i': continue if np.sum(mask) == 0: print( 'Warning, no trainingset!', 'The method selected didn\'t generate a valid mask. Please input the mask manually.' ) chosen_masks[i] = 'm' ioSeg.save_segmentation_params( result_folder, [os.path.split(fin)[-1] for fin in flist_in], chosen_masks, down_shapes, thinnings, smoothings) if not os.path.exists( os.path.join(result_folder, filename + '_manual' + extension)): m = manualmask.makeManualMask(flist_in[i]) m.show() m.exec() else: print('A previously generated manual mask exists!') _rawmask = imread( os.path.join(result_folder, filename + '_manual' + extension)) mask = segment.smooth_mask(_rawmask, mode='manual', down_shape=down_shapes[i],
def computeMaskForAll(self): self.read_segmentation_params() save_folder = os.path.join(self.imageFolder, 'result_segmentation') folder, cond = os.path.split(self.imageFolder) ############################################# # clean masks previously generated ############################################# flist_to_remove = io.get_image_list(save_folder, '_finalMask', 'include') for f in flist_to_remove: os.remove(f) segm_params = os.path.join(save_folder, 'segmentation_params.csv') if os.path.exists(segm_params): os.remove(segm_params) morpho_file = os.path.join(save_folder, cond + '_morpho_params.json') if os.path.exists(morpho_file): os.remove(morpho_file) ############################################# # save parameters used to make segmentation ############################################# ioSeg.save_segmentation_params( save_folder, [os.path.split(fin)[-1] for fin in self.flist_in], self.chosen_masks, self.down_shapes, self.thinnings, self.smoothings) ############################################# # generate final mask ############################################# print('### Generating the smoothened masks.') for i in tqdm.tqdm(range(self.n_imgs)): folder, filename = os.path.split(self.flist_in[i]) filename, extension = os.path.splitext(filename) # print(i, filename) if self.chosen_masks[i] == 'w': _rawmask = imread( os.path.join(self.imageFolder, 'result_segmentation', filename + '_watershed' + extension)) mask = segment.smooth_mask(_rawmask, mode='watershed', down_shape=self.down_shapes[i], smooth_order=self.smoothings[i]) while (np.sum(mask) == 0) & (self.smoothings[i] > 5): print('Mask failed...') # if mask is zero, try smoothing less self.smoothings[i] -= 2 print('Trying with: smoothing', self.smoothings[i]) mask = segment.smooth_mask(_rawmask, mode='watershed', down_shape=self.down_shapes[i], smooth_order=self.smoothings[i]) elif self.chosen_masks[i] == 'c': _rawmask = imread( os.path.join(self.imageFolder, 'result_segmentation', filename + '_classifier' + extension)) mask = segment.smooth_mask(_rawmask, mode='classifier', down_shape=self.down_shapes[i], smooth_order=self.smoothings[i], thin_order=self.thinnings[i]) while (np.sum(mask) == 0) & (self.smoothings[i] > 5) & (self.thinnings[i] > 1): print('Mask failed...') # if mask is zero, try smoothing less self.smoothings[i] -= 2 self.thinnings[i] -= 1 print('Trying with: smoothing', self.smoothings[i], ' thinnings', self.thinnings[i]) mask = segment.smooth_mask(_rawmask, mode='classifier', down_shape=self.down_shapes[i], smooth_order=self.smoothings[i], thin_order=self.thinnings[i]) elif self.chosen_masks[i] == 'm': if not os.path.exists( os.path.join(self.imageFolder, 'result_segmentation', filename + '_manual' + extension)): self.m = GUIs.manualmask.makeManualMask(self.flist_in[i]) self.m.show() self.m.exec() else: print('A previously generated manual mask exists!') _rawmask = imread( os.path.join(self.imageFolder, 'result_segmentation', filename + '_manual' + extension)) mask = segment.smooth_mask(_rawmask, mode='manual', down_shape=self.down_shapes[i], smooth_order=self.smoothings[i]) while (np.sum(mask) == 0) & (self.smoothings[i] > 5): print('Mask failed...') # if mask is zero, try smoothing less self.smoothings[i] -= 2 print('Trying with: smoothing', self.smoothings[i]) # if mask is zero, try smoothing less self.smoothings[i] -= 2 mask = segment.smooth_mask(_rawmask, mode='manual', down_shape=self.down_shapes[i], smooth_order=self.smoothings[i]) elif self.chosen_masks[i] == 'i': continue if np.sum(mask) == 0: QMessageBox.warning( self, 'Warning, no trainingset!', 'The method selected didn\'t generate a valid mask. Please input the mask manually.' ) self.chosen_masks[i] = 'm' ioSeg.save_segmentation_params( save_folder, [os.path.split(fin)[-1] for fin in self.flist_in], self.chosen_masks, self.down_shapes, self.thinnings, self.smoothings) if not os.path.exists( os.path.join(self.imageFolder, 'result_segmentation', filename + '_manual' + extension)): self.m = GUIs.manualmask.makeManualMask(self.flist_in[i]) self.m.show() self.m.exec() else: print('A previously generated manual mask exists!') _rawmask = imread( os.path.join(self.imageFolder, 'result_segmentation', filename + '_manual' + extension)) mask = segment.smooth_mask(_rawmask, mode='manual', down_shape=self.down_shapes[i], smooth_order=self.smoothings[i]) ioSeg.save_segmentation_params( save_folder, [os.path.split(fin)[-1] for fin in self.flist_in], self.chosen_masks, self.down_shapes, self.thinnings, self.smoothings) # save final mask new_name = os.path.join(folder, 'result_segmentation', filename + '_finalMask' + extension) imsave(new_name, mask) print('### Done computing masks!') ############################################# # compute morphology ############################################# # props = DatasetTools.morphology.computemorphology.compute_morphological_info(self.imageFolder, self.compute_meshgrid.isChecked()) # DatasetTools.morphology.io.save_morpho_params(save_folder, cond, props) ############################################# # generate recap ############################################# w = overview.generate_overview_finalMask( self.imageFolder, chosen=[c != 'i' for c in self.chosen_masks], saveFig=True, downshape=3) w.show()
def parsing_images(image_folder, mask_folder, identifier_string, objects_at_border=False): # make directories if not already present images_output_dir = os.path.join(image_folder, 'splitObjects') masks_output_dir = os.path.join(images_output_dir, 'result_segmentation') if not os.path.isdir(images_output_dir): os.mkdir(images_output_dir) if not os.path.isdir(masks_output_dir): os.mkdir(masks_output_dir) # read images and append if only one channel is present/only greyscale image flist_in = io.get_image_list(image_folder, string_filter=identifier_string, mode_filter='exclude') img_to_crop = [] for f in flist_in: img = imread(f) if img.ndim == 2: img = np.expand_dims(img, 0) if img.shape[-1] == np.min(img.shape): img = np.moveaxis(img, -1, 0) img_to_crop.append(img) # read masks/groundtruth flist_mask = io.get_image_list(mask_folder, string_filter=identifier_string, mode_filter='include') # check that number of masks = number of images, otherwise, find missing mask if len(flist_in) != len(flist_mask): for f_in in flist_in: parent, filename = os.path.split(f_in) filename, file_extension = os.path.splitext(filename) mask_name = os.path.join( image_folder, filename + identifier_string + file_extension) if mask_name not in flist_mask: print('\"' + mask_name + '\" not found!') sys.exit( 'Please check that mask is present for every image in input folder!' ) # read and convert masks mask_to_crop = [imread(f) for f in flist_mask] mask_to_crop = [g.astype(int) for g in mask_to_crop] for i in range(len(mask_to_crop)): region_counter = 0 # label mask labeled_mask, num_features = label(mask_to_crop[i], return_num=True) # for saving of cropped regions parent, filename = os.path.split(flist_in[i]) filename, file_extension = os.path.splitext(filename) img_new_name = os.path.join( masks_output_dir, filename + "_cropped_mask" + file_extension) for region in measure.regionprops(labeled_mask): # compute coordinates of regions [min_row, min_col, max_row, max_col] = region.bbox # exclude objects at edge if required if not objects_at_border: if min_row == 0 or min_col == 0 or \ max_row == labeled_mask.shape[0] or max_row == labeled_mask.shape[1]: # leave cropped objects_at_border in a different folder border_objects_output_dir = os.path.join( images_output_dir, 'objects_at_image_border') if not os.path.isdir(border_objects_output_dir): os.mkdir(border_objects_output_dir) cropped_mask = mask_to_crop[i][min_row:max_row, min_col:max_col] cropped_img = img_to_crop[i][:, min_row:max_row, min_col:max_col] # save cropped regions img_new_name = os.path.join( border_objects_output_dir, filename + "_cropped%02d" % region_counter + file_extension) mask_new_name = os.path.join( border_objects_output_dir, filename + "_cropped%02d_finalMask" % region_counter + file_extension) imsave(mask_new_name, cropped_mask.astype(np.uint8)) imsave(img_new_name, cropped_img) region_counter += 1 continue # crop images and masks based on coordinates of regions in mask cropped_mask = mask_to_crop[i][min_row:max_row, min_col:max_col] cropped_img = img_to_crop[i][:, min_row:max_row, min_col:max_col] # save cropped regions img_new_name = os.path.join( images_output_dir, filename + "_cropped%02d" % region_counter + file_extension) mask_new_name = os.path.join( masks_output_dir, filename + "_cropped%02d_finalMask" % region_counter + file_extension) imsave(mask_new_name, cropped_mask.astype(np.uint8)) imsave(img_new_name, cropped_img) region_counter += 1 # save parameters flist_cropped_images = io.get_image_list(images_output_dir) filenames = [os.path.split(fin)[1] for fin in flist_cropped_images] chosen_mask = 'user input' down_shape = 0.5 thinning = smoothing = 'N.A.' ioSeg.save_segmentation_params(masks_output_dir, filenames, chosen_mask, down_shape, thinning, smoothing) # compute morphological information # props = computemorphology.compute_morphological_info( # images_output_dir, compute_meshgrid=False) # ioMorph.save_morpho_params(masks_output_dir, 'splitObjects', props) print('Done!') return