def main(): size = int("${size}") margin = int("${wsi_margin}") # Load sample slide = open_image("${sample}") mask = io.imread("${mask}")[:, :, 0] original_size = get_whole_image(slide, slide.level_count - 2).shape mask = resize(mask, original_size[:2], preserve_range=True, anti_aliasing=True, order=0) # Load segmentation_model opt = type('', (), {})() opt.meta = os.path.join("${model}", "meta.pkl") opt.backbone, opt.model = get_backbone_model( os.path.join("${model}", "final_score.csv")) opt.weights = os.path.join("${model}", "model_weights.h5") opt.mean, opt.std = load_meta(opt.meta) model = load_model_v2(opt.backbone, opt.model, opt.weights) # Divide and analyse list_positions = tile(slide, 0, mask, size, margin, slide.level_count - 2) raw, segmented_tiles = wsi_analysis(slide, model, size, list_positions, margin, opt) np.savez("segmented_tiles.npz", tiles=segmented_tiles, positions=list_positions, raw=raw)
def tile_image(wsi, xml, outfolder, level, size): """Downsize at level and save a WSI in the output folder Parameters ---------- wsi : str path to the WSI. May also be an openslide image. outfolder : str path where to stock the image level : int level to which downsample """ name_wsi, ext = os.path.splitext(os.path.basename(wsi)) slide = usi.open_image(wsi) mask_level = 3 new_path = os.path.join(outfolder, name_wsi) #os.makedirs(new_path) mask_function = lambda x: get_polygon(path_xml=xml, label='t') param_tiles = usi.patch_sampling(slide=wsi, mask_level=mask_level, mask_function=mask_function, sampling_method='grid', analyse_level=level, patch_size=(size, size)) return len(param_tiles)
def main(): args = get_options() model = prep_model(args.weight) mask_level = open_image(args.slide).level_count - 2 analyse_level = args.analyse_level info, encoded = encode_patient(args.slide, args.xml_file, analyse_level, mask_level, model) name_encoded = os.path.basename(args.slide).replace('.tiff', '.npy') name_mean = os.path.basename(args.slide).replace('.tiff', '_mean.npy') name_visu = os.path.basename(args.slide).replace('.tiff', '_visu.png') with open( os.path.basename(args.slide).replace('.tiff', "_info.txt"), "wb") as fp: #Pickling pickle.dump(info, fp) np.save(name_encoded, encoded.astype('float32')) np.save(name_mean, encoded.mean(axis=(0)).astype('float32')) ## for tissue check: # matplotlib without import matplotlib as mpl mpl.use('Agg') import matplotlib.pyplot as plt PLOT_ARGS = { 'color': 'red', 'size': (12, 12), 'with_show': False, 'title': "n_tiles={}".format(len(info)) } visualise_cut(args.slide, info, res_to_view=mask_level, plot_args=PLOT_ARGS) plt.savefig(name_visu)
return options if __name__ == "__main__": options = get_options() out = options.out + "_tiles.txt" out_visu = options.out + "_visualisation.png" # because we are doing UNet! :-) this should disappear image = options.slide extension = image.split('.')[-1] overlap = options.marge + 92 ## because we do segmentation with UNet and we need padding slide_file_name = os.path.basename(options.slide).replace( ".{}".format(extension), "") mask_level = open_image(image).level_count - 2 def load_gt(img): ## dirty trick to keep it compatible lbl = make_label_with_otsu(options.xml_file, img) return lbl options_applying_mask = { 'mask_level': mask_level, 'mask_function': load_gt } ## Options regarding the sampling. Method, level, size, if overlapping or not. ## You can even use custom functions. Tolerance for the mask segmentation. ## allow overlapping is for when the patch doesn't fit in the image, do you want it? ## n_samples and with replacement are for the methods random_patch
parser.add_option("--slide", dest="slide",type="string", help="slide to get dimensions of wsi") (options, _) = parser.parse_args() return options if __name__ == "__main__": options = get_options() margin = options.marge basename = os.path.basename(options.slide).split('.')[0] # output wsi size_x, size_y = open_image(options.slide).dimensions img = pyvips.Image.black(size_x, size_y) # files to iterate over files = join(options.input, "*.tif") for f in tqdm(glob(files)): tile = pyvips.Image.new_from_file(f, access=pyvips.Access.SEQUENTIAL) _, _x, _y, _size_x, level = f.split('/')[-1].split('.')[0].split('_') _size_y = _size_x _size_x, _size_y = int(_size_x) - 2 * margin, int(_size_y) - 2 * margin sub_tile = tile.extract_area(margin, margin, _size_x, _size_y) img = img.insert(sub_tile, int(_x) + margin, int(_y) + margin)
def from_cell_to_heatmap(slide, trans, cell_table, filter_out="LBP", level=7, n_comp=2): """ Parameters ---------- slide : wsi object, openslide object from which we extract. trans : function, infers the new coordinates of a given point. It is or: - the sequential application of PCA+UMAP - application of UMAP. cell_table : pandas dataframe, patient table, where each line corresponds to a nucleus. filter_out: str, String pattern to filter out columns from the feature table, in 'glob' form. If pattern in the feature name, exclude feature. level : int, level of the resulting heatmap. n_comp : int, number of components after UMAP projection. Returns ------- Returns a heatmap with the projected components of a given slide at a given resolution. """ slide = open_image(slide) f1, f2 = normalise_csv(cell_table) feat = f1.columns feat = [el for el in feat if filter_out not in el] f1 = f1[feat] f1 = drop_na_axis(f1) standard_embedding = trans(f1) x = standard_embedding[:, 0] y = standard_embedding[:, 1] if level < slide.level_count: # if the pyramid scheme has a the png at the correct resolution shape_slide_level = get_whole_image(slide, level=level, numpy=True).shape within_slide_levels = True else: # if the pyramid scheme doesn't have the png at the correct resolution within_slide_levels = False high_pyramid_level = slide.level_count - 1 power = level - high_pyramid_level shape_slide_level = get_whole_image(slide, level=high_pyramid_level, numpy=True).shape shape_slide_level = tuple((int(shape_slide_level[0] / (2**power)), int(shape_slide_level[1] / (2**power)), 3)) xshape, yshape = shape_slide_level[0:2] f2["coord_l"] = f2.apply(lambda row: f(slide, row, shape_slide_level), axis=1) heatmap = np.zeros(shape=(xshape, yshape, 3)) f1 = f1.reset_index(drop=True) f2 = f2.reset_index(drop=True) for coord_l, group in tqdm(f2.groupby("coord_l")): y_l, x_l = [int(el) for el in coord_l] heatmap[x_l, y_l, 0] = np.mean(x[group.index]) heatmap[x_l, y_l, 1] = np.mean(y[group.index]) if n_comp == 2: count = group.shape[0] heatmap[x_l, y_l, 2] = count else: z = standard_embedding[:, 2] heatmap[x_l, y_l, 2] = np.mean(z[group.index]) return heatmap