I used this solution. I created a custom open()
method that takes a tuple of file path and tile index and returns a fastai Image
of the selected tile. Then I customized also from_folder()
method.
ImageTile = namedtuple('ImageTile', 'path idx rows cols')
def calc_n_tiles(size, tile_max_size):
x, y = size
n_cols = x % (x // tile_max_size + 1)
n_rows = y % (y // tile_max_size + 1)
return n_rows, n_cols, (x//n_cols, y//n_rows)
def get_labels_tiles(fn):
path, *tile = fn
path = path_lbl / path.name
return ImageTile(path, *tile)
def get_tiles(images: PathOrStr, rows: int, cols: int) -> Collection[ImageTile]:
images_tiles = []
for img in images:
for i in range(rows * cols):
images_tiles.append(ImageTile(img, i, rows, cols))
return images_tiles
def open_image_tile(img_t: ImageTile, mask=False, **kwargs) -> Image:
"""given and ImageTile it returns and Image with the tile,
set mask to True for masks"""
path, idx, rows, cols = img_t
img = open_image(path, **kwargs) if not mask else open_mask(path, **kwargs)
row = idx // cols
col = idx % cols
tile_x = img.size[0] // cols
tile_y = img.size[1] // rows
return Image(img.data[:, col * tile_x:(col + 1) * tile_x, row * tile_y:(row + 1) * tile_y])
class SegmentationTileLabelList(SegmentationLabelList):
def open(self, fn: ImageTile):
return open_image_tile(fn, div=True, mask=True)
class SegmentationTileItemList(ImageList):
_label_cls, _square_show_res = SegmentationTileLabelList, False
def open(self, fn: ImageTile) -> Image:
return open_image_tile(fn, convert_mode=self.convert_mode, after_open=self.after_open)
@classmethod
def from_folder(cls, path: PathOrStr = '.', rows=1, cols=1, extensions: Collection[str] = None, **kwargs) -> ItemList:
"""patchs the from_folder method, generating list of ImageTile with all the possible tiles for all the images in folder"""
files = get_files(path, extensions, recurse=True)
files_tiled = get_tiles(files, rows, cols)
return SegmentationTileItemList(files_tiled, **kwargs)
Hope this is not a silly approach and it can bu useful.