def getnewMask(seg_file,dilation,WS_outfile,WS_transfile,WS_maskImage): temp = np.asarray(np.load(seg_file,allow_pickle=True)).item() masks_1 = temp['masks'] im = np.zeros_like(np.array(masks_1)) points_frame = pd.DataFrame(measure.regionprops_table(masks_1, properties=['label','centroid'])) pointList = np.array(points_frame.iloc[:,-2:].astype(int)) for x in range(pointList.shape[0]): im[pointList[x,0],pointList[x,1]] = 1 masks = temp['masks']>0 masks=morphology.dilation(masks,morphology.disk(dilation)) secmask = np.zeros(masks.shape, dtype=bool) secmask[tuple(pointList.T)] = True secmask = morphology.dilation(secmask,morphology.square(3)) markers, _ = ndi.label(secmask) labels = segmentation.watershed( -im, markers, mask=(masks>0)) np.save(WS_outfile, labels, allow_pickle=True, fix_imports=True) points_frame['newLabel'] = [labels[pointList[x,0],pointList[x,1]] for x in range(pointList.shape[0])] points_frame.to_csv(WS_transfile) io.imsave(WS_maskImage, segmentation.find_boundaries(labels))
def test_class_3D(data_dir, image_names): clear_output(data_dir, image_names) img = io.imread(str(data_dir.joinpath('3D').joinpath('rgb_3D.tif'))) model_types = ['nuclei'] chan = [1] chan2 = [0] for m,model_type in enumerate(model_types): model = models.Cellpose(model_type='nuclei') masks = model.eval(img, do_3D=True, diameter=25, channels=[chan[m],chan2[m]], net_avg=False)[0] io.imsave(str(data_dir.joinpath('3D').joinpath('rgb_3D_cp_masks.tif')), masks) compare_masks(data_dir, ['rgb_3D.tif'], '3D', model_type) clear_output(data_dir, image_names)
def test_class_2D(data_dir, image_names): clear_output(data_dir, image_names) img = io.imread(str(data_dir.joinpath('2D').joinpath('rgb_2D.png'))) model_types = ['nuclei'] chan = [1] chan2 = [0] for m,model_type in enumerate(model_types): model = models.Cellpose(model_type=model_type) masks, flows, _, _ = model.eval(img, diameter=0, channels=[chan[m],chan2[m]], net_avg=False) io.imsave(str(data_dir.joinpath('2D').joinpath('rgb_2D_cp_masks.png')), masks) compare_masks(data_dir, ['rgb_2D.png'], '2D', model_type) clear_output(data_dir, image_names) if MATPLOTLIB: fig = plt.figure(figsize=(8,3)) plot.show_segmentation(fig, img, masks, flows[0], channels=[chan[m],chan2[m]])
def getVoronoiStyle(seg_file,max_voro_area,voro_imfile,voro_imfile_2,voro_outfile,voro_transfile): temp = np.asarray(np.load(seg_file,allow_pickle=True)).item() masks = temp['masks'] im = np.zeros_like(np.array(masks)) fro = pd.DataFrame(measure.regionprops_table(masks, properties=['label','centroid'])) points_mask = np.array(fro[['centroid-0','centroid-1']].to_numpy()) vor = Voronoi(points_mask) my_dpi=im.shape[1] plt.rcParams['figure.dpi'] = my_dpi plt.rcParams['figure.figsize'] = ( im.shape[0]/my_dpi,im.shape[1]/my_dpi) fig = plt.figure(); for simplex in vor.ridge_vertices: simplex = np.asarray(simplex) if np.all(simplex >= 0): plt.plot(vor.vertices[simplex, 0], vor.vertices[simplex, 1], 'k-',c='black',linewidth=.2) center = points_mask.mean(axis=0) for pointidx, simplex in zip(vor.ridge_points, vor.ridge_vertices): simplex = np.asarray(simplex) if np.any(simplex < 0): i = simplex[simplex >= 0][0] # finite end Voronoi vertex t = points_mask[pointidx[0]] - points_mask[pointidx[1]] # tangent t = t / np.linalg.norm(t) n = np.array([-t[1], t[0]]) # normal midpoint = points_mask[pointidx].mean(axis=0) far_point = vor.vertices[i] + np.sign(np.dot(midpoint - center, n)) * n * 100 plt.plot([vor.vertices[i,0], far_point[0]], [vor.vertices[i,1], far_point[1]], 'k-',c='black',linewidth=.2) plt.xlim([0, im.shape[0]]); plt.ylim([0,im.shape[1]]) plt.axis('off') fig.tight_layout(pad=0) plt.savefig(voro_imfile, dpi=my_dpi, #bbox_inches='tight',#dpi=my_dpi, transparent=False, pad_inches=0,facecolor='white') plt.close() im2 = io.imread(voro_imfile) voro = (im2[:,:,0]) voro = voro[1:-1, 1:-1] voro = np.pad(voro, pad_width=1, mode='constant') distance = ndi.distance_transform_edt(voro) coords = peak_local_max(distance, footprint=np.ones((1, 1)), labels=voro) mask = np.zeros(distance.shape, dtype=bool) mask[tuple(coords.T)] = True markers, _ = ndi.label(mask) labels = segmentation.watershed(-distance, markers, mask=voro) labels = morphology.remove_small_objects(labels, min_size=40, connectivity=1, in_place=False) labels = morphology.dilation(labels, morphology.square(3)) segmasks = masks segmasks = morphology.dilation(segmasks,morphology.square(3)) sizeOfSegs = pd.DataFrame(measure.regionprops_table(labels, properties=['label','area'])) bigMasks = np.array(sizeOfSegs[sizeOfSegs['area']>=max_voro_area]['label']) newVorMask = np.copy(labels)[::-1,:] for bMI in range(len(bigMasks)): print("progress:"+str(bMI)+'/'+str(len(bigMasks))) chckMtx = (labels == bigMasks[bMI])[::-1,:] for i in range(len(points_mask)): confirm = points_mask[i] print(points_mask[i]) print("---") tmp_cellpose_mask = (morphology.dilation((segmasks == int(fro[(fro['centroid-0']==confirm[0])&(fro['centroid-1']==confirm[1])]['label'])).T,morphology.disk(11))).astype(int) tmp_voronoi_mask = 2*chckMtx.astype(int) tmp_join = segmentation.join_segmentations(tmp_cellpose_mask,tmp_voronoi_mask) tmp_join = (tmp_join == np.max(tmp_join)) newVorMask[newVorMask == bigMasks[bMI]] = 0 newVorMask[tmp_join] = bigMasks[bMI] np.save(voro_outfile, newVorMask.T, allow_pickle=True, fix_imports=True) io.imsave(voro_imfile_2, segmentation.find_boundaries(newVorMask).T) oldAssign = pd.DataFrame(measure.regionprops_table(masks, properties=['label','centroid'])) newAssign = pd.DataFrame(measure.regionprops_table(newVorMask, properties=['label','centroid'])) Clps2Voro = pd.DataFrame() for nlab in range(newAssign.shape[0]): tmpMtx = (newVorMask == newAssign['label'][nlab]) for olab in range(oldAssign.shape[0]): if (tmpMtx[int(np.round(oldAssign['centroid-1'][olab])),int(np.round(oldAssign['centroid-0'][olab]))]): Clps2Voro = Clps2Voro.append(pd.DataFrame([newAssign['label'][nlab], oldAssign['label'][olab]]).T) Clps2Voro = Clps2Voro.rename(columns={0: "voro_label", 1: "clps_label"}) Clps2Voro = Clps2Voro.reset_index(drop=True) Clps2Voro.to_csv(voro_transfile)
def folder_prepare_prediction(path_process, channel_ident, img_ext, path_save, projection_type, subfolder=None, search_recursive=False, callback_log=None, callback_status=None, callback_progress=None): """[summary] Parameters ---------- path_process : [type] [description] channel_ident : str [description] img_ext : str Image extension path_save : pathlin object or string Path to save results, - If Pathlib object, then this absolute path is used. - If 'string' a replacement operation on the provided name of the data path will be applied (see create_output_path). And results will be stored in subfolder 'segmentation-input' projection_type : [type] [description] subfolder: str subfolder where data should be stored. Will only be used when string replacement for path is used. search_recursive : bool Recursively search folder, default: false. callback_log : [type], optional [description], by default None callback_status : [type], optional [description], by default None callback_progress : [type], optional [description], by default None """ # Print all input parameters log_message(f"Function (segment_obj_indiv) called with: {str(locals())} ", callback_fun=callback_log) # Use provided absolute user-path to save images. if isinstance(path_save, pathlib.PurePath): path_save_results = path_save if not path_save_results.is_dir(): path_save_results.mkdir(parents=True) path_save_settings = path_save_results else: path_save_str_replace = path_save # How to look for files files_proc = [] if search_recursive: for path_img in path_process.rglob(f'*{channel_ident}*{img_ext}'): files_proc.append(path_img) else: for path_img in path_process.glob(f'*{channel_ident}*{img_ext}'): files_proc.append(path_img) # Process files n_files = len(files_proc) for idx, file_proc in enumerate(files_proc): log_message(f'\n>>> Processing file: {file_proc}', callback_fun=callback_status) if callback_progress: progress = float((idx + 1) / n_files) callback_progress(progress) name_base = file_proc.stem # Create new output path if specified if not isinstance(path_save, pathlib.PurePath): path_save_results = create_output_path(file_proc.parent, path_save_str_replace, subfolder=subfolder, create_path=True) log_message(f'Results will be save here : {path_save_results}', callback_fun=callback_status) path_save_settings = path_save_results # Create subfolder when processing individual images if projection_type == 'indiv': path_save_indiv = path_save_results / name_base if not path_save_indiv.is_dir(): path_save_indiv.mkdir(parents=True) path_save_settings = path_save_indiv # Open image print(file_proc) img = imread(str(file_proc)) img_properties = { "file_process": str(file_proc), "img_name": file_proc.name, "img_path": str(file_proc.parent), "channel_ident": channel_ident, "projection_type": projection_type } name_json = path_save_settings / f'img-prop__{name_base}.json' with open(name_json, 'w') as fp: json.dump(img_properties, fp, sort_keys=True, indent=4) # Process depending specified option if projection_type == 'indiv': for i in range(img.shape[0]): name_save = path_save_indiv / f'{name_base}_Z{str(i+1).zfill(3)}.png' if name_save.is_file(): log_message( f'File already exists. Will be overwritten {name_save}', callback_fun=callback_log) imsave(str(name_save), img[i, :, :]) else: if projection_type == 'mean': img_proj = img.mean(axis=0) elif projection_type == 'max': img_proj = img.max(axis=0) name_save = path_save_results / f'{name_base}.png' if name_save.is_file(): log_message( f'File already exists. Will be overwritten {name_save}', callback_fun=callback_log) imsave(str(name_save), img_proj.astype('uint16'))
def cellpose_predict(data, config, path_save, callback_log=None): """ Perform prediction with CellPose. Parameters ---------- data : dict Contains data on which prediction should be performed. config : dict Configuration of CellPose prediction. path_save : pathline Path object Path where results will be saved. """ # Get data imgs = data['imgs'] file_names = data['file_names'] channels = data['channels'] obj_name = data['obj_name'] sizes_orginal = data['sizes_orginal'] new_size = data['new_size'] # Get config model_type = config['model_type'] diameter = config['diameter'] net_avg = config['net_avg'] resample = config['resample'] log_message(f'\nPerforming segmentation of {obj_name}\n', callback_fun=callback_log) start_time = time.time() if not path_save.is_dir(): path_save.mkdir() # Perform segmentation with CellPose model = models.Cellpose( gpu=False, model_type=model_type) # model_type can be 'cyto' or 'nuclei' masks, flows, styles, diams = model.eval(imgs, diameter=diameter, channels=channels, net_avg=net_avg, resample=resample) # Display and save results log_message(f'\n Creating outputs ...\n', callback_fun=callback_log) n_img = len(imgs) for idx in tqdm(range(n_img)): # Get images and file-name file_name = file_names[idx] maski = masks[idx] flowi = flows[idx][0] imgi = imgs[idx] # Rescale each channel separately imgi_norm = imgi.copy() for idim in range(3): imgdum = imgi[:, :, idim] # Renormalize to 8bit between 1 and 99 percentile pa = np.percentile(imgdum, 0.5) pb = np.percentile(imgdum, 99.5) if pb > pa: imgi_norm[:, :, idim] = 255 * (imgdum - pa) / (pb - pa) # Save flow io.imsave(str(path_save / f'{file_name.stem}__flow__{obj_name}.png'), flowi) # Resize masks if necessary if new_size: mask_full = resize_mask(maski, sizes_orginal[idx]) io.imsave( str(path_save / f'{file_name.stem}__mask__{obj_name}.png'), mask_full) io.imsave( str(path_save / f'{file_name.stem}__mask_resize__{obj_name}.png'), maski) else: io.imsave( str(path_save / f'{file_name.stem}__mask__{obj_name}.png'), maski) # Save mask and flow images #f_mask = str(path_save / f'{file_name.stem}__mask__{obj_name}.png') #log_message(f'\nMask saved to file: {f_mask}\n', callback_fun=callback_log) #io.imsave(str(path_save / f'{file_name.stem}__mask__{obj_name}.png'), maski) # Save overview image fig = plt.figure(figsize=(12, 3)) plot.show_segmentation(fig, imgi_norm.astype('uint8'), maski, flowi) plt.tight_layout() fig.savefig(str(path_save / f'{file_name.stem}__seg__{obj_name}.png'), dpi=300) plt.close(fig) log_message( f"\nSegmentation of provided images finished ({(time.time() - start_time)}s)", callback_fun=callback_log)