Sorry, I think I am not explaining myself correctly.
The goal I want to accomplish is to tile a WSI in patches of a given size.
In the code I am using now I use read_region
function from openslide-python and I saved the tile using .save
function.
I would like to do this using bioformats, since it manages much better Ventana bif files than openslide does. I add here a code snippet of the function adapted from here in order to make things more clear:
def wsi2mosaic(image, size, overlap, level, drop_last=False, return_coords=False, only_list=False, check_tissue=True, prefix='', suffix='.png'):
assert isinstance(image, openslide.OpenSlide), "input image should be an openslide wsi"
assert level < len(image.level_dimensions), f"this image has only {len(image.level_dimensions)} levels"
if type(size) is list:
assert len(size) == 2, "size should be integer or [size_h, size_w]"
s_h = size[0]
s_w = size[1]
else:
assert isinstance(size, int), "size should be integer or [size_h, size_w]"
s_h = size
s_w = size
if type(overlap) is list:
assert len(size) == 2, "overlap should be integer or [overlap_h, overlap_w]"
o_h = size[0]
o_w = size[1]
else:
assert isinstance(overlap, int), "overlap should be integer or [overlap_h, overlap_w]"
o_h = overlap
o_w = overlap
w_wsi, h_wsi = image.dimensions #! openslide image dimensions: WxH
w_lvl, h_lvl = image.level_dimensions[level]
box_coords_wsi = [0,0, h_wsi, w_wsi] #This way you avoid keeping only the biggest part of the tissue
box_coords_wsi = [[box_coords_wsi[0], box_coords_wsi[1]],[box_coords_wsi[2], box_coords_wsi[3]]]
box_coords_lvl = getScaledCoordinates(box_coords_wsi, [h_wsi,w_wsi], [h_lvl,w_lvl])
h_box_lvl = box_coords_lvl[1][0] - box_coords_lvl[0][0]
w_box_lvl = box_coords_lvl[1][1] - box_coords_lvl[0][1]
assert h_box_lvl>s_h, f"tile height ({s_h}) should be less than box level height ({h_box_lvl})"
assert w_box_lvl>s_w, f"tile width ({s_w}) should be less than box level width ({w_box_lvl})"
x_ = np.arange(box_coords_lvl[0][0], box_coords_lvl[1][0]-s_h+1, s_h-o_h)
y_ = np.arange(box_coords_lvl[0][1], box_coords_lvl[1][1]-s_w+1, s_w-o_w)
if not drop_last:
x_ = np.hstack([x_, [box_coords_lvl[1][0]-s_h]])
y_ = np.hstack([y_, [box_coords_lvl[1][1]-s_w]])
coords_ul = [(x,y) for x in x_ for y in y_]
coords_br = [(x+s_h,y+s_w) for x in x_ for y in y_]
coord_wsi_ul = getScaledCoordinates(coords_ul, [h_lvl, w_lvl], [h_wsi,w_wsi])
coord_wsi_br = getScaledCoordinates(coords_br, [h_lvl, w_lvl], [h_wsi,w_wsi])
coord_wsi = [(ul[0], ul[1], br[0], br[1]) for ul,br in zip(coord_wsi_ul, coord_wsi_br)]
if return_coords:
return(coord_wsi)
img_list = []
f = open(f'{prefix}_coordinates.csv', 'w')
f.write('coordinates\n')
f.close()
for COORD in coord_wsi:
x_ul = COORD[0]
y_ul = COORD[1]
x_br = COORD[2]
y_br = COORD[3]
tile = image.read_region((y_ul, x_ul), level, (s_w, s_h))
if check_tissue:
tile_np = np.array(tile)
if only_list:
if hasEnoughTissue(tile_np):
f = open(f'{prefix}_coordinates.csv', 'a')
f.write('[{},{}]\n'.format(y_ul, x_ul))
else:
if hasEnoughTissue(tile_np):
tile.save(f'{prefix}_{level}_{x_ul}-{y_ul}-{x_br}-{y_br}_{suffix}')
f = open(f'{prefix}_coordinates.csv', 'a')
f.write('[{},{}]\n'.format(y_ul, x_ul))
else:
tile.save(f'{prefix}_{level}_{x_ul}-{y_ul}-{x_br}-{y_br}_{suffix}')
f = open(f'{prefix}_coordinates.csv', 'a')
f.write('[{},{}]\n'.format(x_ul, y_ul))
Ignoring the extra functions that are not pasted, the idea of the script is to tile an image at a given level
. Here, what I would like to do is, ideally, change the tile = image.read_region((y_ul, x_ul), level, (s_w, s_h))
inside the for loop with something equivalent in python-bioformats
.