def test_constant_mode(self): # Constant mode pads the non-full tiles with constant_value tile_size = 15 constant_value = -99 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, ), mode='constant', constant_value=constant_value) expected_split = [ self.data[i:i + tile_size] for i in range(0, self.n_elements, tile_size) ] expected_split[-1] = np.pad(expected_split[-1], (0, tile_size - len(expected_split[-1])), mode='constant', constant_values=constant_value) calculated_split = [t for _, t in tiler(self.data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split) # Constant mode with tile shape bigger than data tiler = Tiler(data_shape=(1, 63), tile_shape=(1, 64), mode='constant') self.assertEqual(tiler.n_tiles, 1)
def __init__(self, tiled_image): from tiled_image import TiledImage assert isinstance(tiled_image, TiledImage); Tiler.__init__(self, tiled_image) self.tile_path = tiled_image.image_path self.background = tiled_image.background
def test_drop_mode(self): # Drop mode drops last uneven tile tile_size = 15 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, ), mode='drop') expected_split = [ self.data[i:i + tile_size] for i in range(0, self.n_elements, tile_size) ] expected_split = expected_split[:-1] calculated_split = [t for _, t in tiler(self.data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split) # Drop mode with overlap bigger than any of the dimensions with self.assertRaises(ValueError): Tiler(data_shape=(2, 100), tile_shape=(1, 64), overlap=32, mode='drop') # Drop mode with tile shape bigger than data shape with warnings.catch_warnings(): warnings.simplefilter('ignore') tiler = Tiler(data_shape=(1, 63), tile_shape=(1, 64), mode='drop') self.assertEqual(tiler.n_tiles, 0)
def test_channel_dimensions(self): tile_size = 15 data = np.vstack((self.data, self.data * 2, self.data * 3)) tiler = Tiler(data_shape=data.shape, tile_shape=(3, tile_size), mode='irregular', channel_dimension=0) expected_split = [[ data[0][i:i + tile_size], data[1][i:i + tile_size], data[2][i:i + tile_size] ] for i in range(0, self.n_elements, tile_size)] calculated_split = [t for _, t in tiler(data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split) # test negative indexing tiler = Tiler(data_shape=data.shape, tile_shape=(3, tile_size), mode='irregular', channel_dimension=-2) expected_split = [[ data[0][i:i + tile_size], data[1][i:i + tile_size], data[2][i:i + tile_size] ] for i in range(0, self.n_elements, tile_size)] calculated_split = [t for _, t in tiler(data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split)
def __init__(self, infile, media_id=None, filext='jpg', tilesize=256): Tiler.__init__(self, infile, media_id, filext, tilesize) try: self.__ppm_fileobj = open(self._infile, 'rb') except IOError: raise self._width, self._height = read_ppm_header(self.__ppm_fileobj) self._bytes_per_pixel = 3
def __init__(self, tiled_image, source_path): from tiled_image import TiledImage assert isinstance(tiled_image, TiledImage); Tiler.__init__(self, tiled_image) self.tile_path = tiled_image.image_path self.background = tiled_image.background self.source_path = source_path self.source_image = Image.open(source_path) print "Tiling: %s as: %s" % (source_path, self.tile_path) print "Format: %s, Size: %s, Mode: %s" % ( self.source_image.format, self.source_image.size, self.source_image.mode)
def test_init(self): with self.assertRaises(ValueError): Tiler(data_shape=(-10, -30), tile_shape=(10, 10)) with self.assertRaises(ValueError): Tiler(data_shape=(100, 300), tile_shape=(-10, -10)) with self.assertRaises(ValueError): Tiler(data_shape=(300, 300), tile_shape=(10, 10, 10)) with self.assertRaises(ValueError): Tiler(data_shape=(300, 300), tile_shape=(10, 10), mode='unsupported_mode') with self.assertRaises(ValueError): Tiler(data_shape=(300, 300), tile_shape=(10, 10), channel_dimension=10) with self.assertRaises(ValueError): Tiler(data_shape=(300, 300), tile_shape=(10, 10), overlap=1337.0) with self.assertRaises(ValueError): Tiler(data_shape=(300, 300), tile_shape=(10, 10), overlap=(15, 0)) with self.assertRaises(ValueError): Tiler(data_shape=(300, 300), tile_shape=(10, 10), overlap='unsupported_overlap')
def test_merge(self): # Test padding tiler = Tiler(data_shape=self.data.shape, tile_shape=(12, )) merger = Merger(tiler) for t_id, t in tiler(self.data): merger.add(t_id, t) np.testing.assert_equal(merger.merge(unpad=True), self.data) np.testing.assert_equal( merger.merge(unpad=False), np.hstack((self.data, [0, 0, 0, 0, 0, 0, 0, 0]))) # Test argmax merger = Merger(tiler, logits=3) for t_id, t in tiler(self.data): merger.add(t_id, np.vstack((t, t / 2, t / 3))) np.testing.assert_equal(merger.merge(unpad=True, argmax=True), np.zeros((100, ))) np.testing.assert_equal( merger.merge(unpad=True, argmax=False), np.vstack((self.data, self.data / 2, self.data / 3))) np.testing.assert_equal(merger.merge(unpad=False, argmax=True), np.zeros((108, ))) np.testing.assert_equal( merger.merge(unpad=False, argmax=False), np.vstack((np.hstack((self.data, [0, 0, 0, 0, 0, 0, 0, 0])), np.hstack((self.data, [0, 0, 0, 0, 0, 0, 0, 0])) / 2, np.hstack((self.data, [0, 0, 0, 0, 0, 0, 0, 0])) / 3)))
def _create_tiler(self): """Create the Tiler instance.""" self._tiler = Tiler( self.reg_transform_seq.output_size, self.zarr_tile_shape, overlap=0, mode="irregular", )
def test_cut_tiles_squared(self): arr = (rand(100, 100, 3) * 255).astype('uint8') image = Image.fromarray(arr).convert('RGBA') tiles = list(Tiler.cut_tiles(image, (10, 10))) assert len(tiles) == 100 last_tile = tiles[-1][0] assert last_tile.size == (10, 10) last_coords = tiles[-1][1] assert last_coords == (9, 9) assert (asarray(last_tile) == asarray(image)[-10:, -10:]).all()
def test_iterator(self): tile_size = 10 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, )) # copy test with iterator t = list(tiler(self.data, copy_data=True)) t[0][1][9] = 0 np.testing.assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], tiler.get_tile(self.data, 0)) np.testing.assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 0], t[0][1]) self.assertNotEqual(t[0][1][9], self.data[9]) t = [tile for _, tile in tiler(self.data, copy_data=False)] t[0][9] = 0 np.testing.assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 0], tiler.get_tile(self.data, 0)) np.testing.assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 0], t[0]) self.assertEqual(t[0][9], self.data[9]) # test batch size with self.assertRaises(ValueError): t = [x for _, x in tiler(self.data, batch_size=-1)] t = [x for _, x in tiler(self.data, batch_size=0)] self.assertEqual(len(t), 10) np.testing.assert_equal(t[0].shape, (10, )) t = [x for _, x in tiler(self.data, batch_size=1)] self.assertEqual(len(t), 10) np.testing.assert_equal(t[0].shape, (1, 10)) t = [x for _, x in tiler(self.data, batch_size=10)] self.assertEqual(len(t), 1) np.testing.assert_equal(t[0].shape, (10, 10)) t = [x for _, x in tiler(self.data, batch_size=9)] self.assertEqual(len(t), 2) np.testing.assert_equal(t[0].shape, (9, 10)) np.testing.assert_equal(t[1].shape, (1, 10)) t = [x for _, x in tiler(self.data, batch_size=9, drop_last=True)] self.assertEqual(len(t), 1) np.testing.assert_equal(t[0].shape, (9, 10))
def test_batch_add(self): tiler = Tiler(data_shape=self.data.shape, tile_shape=(10, )) merger = Merger(tiler) batch1 = [x for _, x in tiler(self.data, False, batch_size=1)] np.testing.assert_equal(len(batch1), 10) np.testing.assert_equal(batch1[0].shape, ( 1, 10, )) for i, b in enumerate(batch1): merger.add_batch(i, 1, b) np.testing.assert_equal(merger.merge(), self.data) merger.reset() batch10 = [x for _, x in tiler(self.data, False, batch_size=10)] for i, b in enumerate(batch10): merger.add_batch(i, 10, b) np.testing.assert_equal(merger.merge(), self.data) merger.reset() batch8 = [x for _, x in tiler(self.data, False, batch_size=8)] np.testing.assert_equal(len(batch8), 2) np.testing.assert_equal(batch8[0].shape, ( 8, 10, )) np.testing.assert_equal(batch8[1].shape, ( 2, 10, )) for i, b in enumerate(batch8): merger.add_batch(i, 8, b) np.testing.assert_equal(merger.merge(), self.data) merger.reset() batch8_drop = [ x for _, x in tiler(self.data, False, batch_size=8, drop_last=True) ] np.testing.assert_equal(len(batch8_drop), 1) np.testing.assert_equal(batch8_drop[0].shape, ( 8, 10, )) for i, b in enumerate(batch8_drop): merger.add_batch(i, 8, b) np.testing.assert_equal(merger.merge()[:80], self.data[:80]) np.testing.assert_equal(merger.merge()[80:], np.zeros((20, ))) with self.assertRaises(IndexError): merger.add_batch(-1, 10, batch10[0]) with self.assertRaises(IndexError): merger.add_batch(10, 10, batch10[9])
def test_cut_tiles_incomplete(self): arr = (rand(95, 45, 3) * 255).astype('uint8') image = Image.fromarray(arr).convert('RGBA') tiles = list(Tiler.cut_tiles(image, (10, 10))) assert len(tiles) == 50 sec_last_tile = tiles[-2][0] assert sec_last_tile.size == (5, 10) sec_last_coords = tiles[-2][1] assert sec_last_coords == (4, 8) last_tile = tiles[-1][0] assert last_tile.size == (5, 5) last_coords = tiles[-1][1] assert last_coords == (4, 9) assert (asarray(last_tile) == asarray(image)[-5:, -5:]).all()
def test_init(self): tiler = Tiler(data_shape=self.data.shape, tile_shape=(10, )) # logits test with self.assertRaises(ValueError): Merger(tiler=tiler, logits=-1) with self.assertRaises(ValueError): Merger(tiler=tiler, logits='unsupported_type') merger = Merger(tiler=tiler) np.testing.assert_equal(merger.data.shape, self.data.shape) merger2 = Merger(tiler=tiler, logits=99) np.testing.assert_equal(merger2.data.shape, (99, ) + self.data.shape)
def test_overlap_tile_window(self): # no overlap is given - the resulting window should be just zeros tiler = Tiler(data_shape=(100, ), tile_shape=(10, ), overlap=0) merger = Merger(tiler=tiler, window='overlap-tile') np.testing.assert_equal(merger.window, np.zeros((10, ))) # odd overlap - discarding overlap // 2 elements from both sides tiler = Tiler(data_shape=(100, ), tile_shape=(10, ), overlap=5) merger = Merger(tiler=tiler, window='overlap-tile') np.testing.assert_equal(merger.window, [0, 0, 1, 1, 1, 1, 1, 1, 0, 0]) # even overlap - discarding overlap // 2 elements from both sides tiler = Tiler(data_shape=(100, ), tile_shape=(10, ), overlap=(6, )) merger = Merger(tiler=tiler, window='overlap-tile') np.testing.assert_equal(merger.window, [0, 0, 0, 1, 1, 1, 1, 0, 0, 0]) # channel dimension case tiler = Tiler(data_shape=(3, 100), tile_shape=(3, 4), channel_dimension=0, overlap=2) merger = Merger(tiler=tiler, window='overlap-tile') np.testing.assert_equal(merger.window, [[0, 1, 1, 0], [0, 1, 1, 0], [0, 1, 1, 0]]) # 2D even case tiler = Tiler(data_shape=(100, 100), tile_shape=(4, 4), overlap=(2, 2)) merger = Merger(tiler=tiler, window='overlap-tile') np.testing.assert_equal( merger.window, [[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]) # 2D odd case tiler = Tiler(data_shape=(100, 100), tile_shape=(4, 4), overlap=3) merger = Merger(tiler=tiler, window='overlap-tile') np.testing.assert_equal( merger.window, [[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]) # Channel + 2D even case tiler = Tiler(data_shape=(3, 100, 100), tile_shape=(3, 4, 4), channel_dimension=0, overlap=2) merger = Merger(tiler=tiler, window='overlap-tile') np.testing.assert_equal( merger.window, [[[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]])
def build_graph(mmw_config, aws_profile, **kwargs): """ Builds graphs for all of the MMW stacks Args: mmw_config (dict): dictionary representation of `default.yml` aws_profile (str): name of AWS profile to use for authentication """ if kwargs['stack_color'] is not None: mmw_config['StackColor'] = kwargs['stack_color'].capitalize() global_config = GlobalConfigNode(**mmw_config) vpc = VPC(globalconfig=global_config, aws_profile=aws_profile) s3_vpc_endpoint = S3VPCEndpoint(globalconfig=global_config, VPC=vpc, aws_profile=aws_profile) private_hosted_zone = PrivateHostedZone(globalconfig=global_config, VPC=vpc, aws_profile=aws_profile) data_plane = DataPlane(globalconfig=global_config, VPC=vpc, PrivateHostedZone=private_hosted_zone, aws_profile=aws_profile) tiler = Tiler(globalconfig=global_config, VPC=vpc, aws_profile=aws_profile, DataPlane=data_plane) tile_delivery_network = TileDeliveryNetwork( globalconfig=global_config, VPC=vpc, PrivateHostedZone=private_hosted_zone, # NOQA aws_profile=aws_profile) application = Application(globalconfig=global_config, VPC=vpc, DataPlane=data_plane, TileDeliveryNetwork=tile_delivery_network, aws_profile=aws_profile) worker = Worker(globalconfig=global_config, VPC=vpc, DataPlane=data_plane, aws_profile=aws_profile) public_hosted_zone = PublicHostedZone(globalconfig=global_config, Application=application, aws_profile=aws_profile) return vpc, s3_vpc_endpoint, data_plane, tiler, application, \ worker, public_hosted_zone
def test_repr(self): # gotta get that coverage tiler = Tiler(data_shape=(3, 300, 300), tile_shape=(3, 15, 300), channel_dimension=0, mode='irregular') expected_repr = 'Tiler split [3, 300, 300] data into 20 tiles of [3, 15, 300].' \ '\n\tMosaic shape: [1, 20, 1]' \ '\n\tPadded shape: [3, 300, 300]' \ '\n\tTile overlap: 0' \ '\n\tElement step: [0, 15, 300]' \ '\n\tMode: irregular' \ '\n\tChannel dimension: 0' self.assertEqual(str(tiler), expected_repr)
def test_irregular_mode(self): # Irregular mode returns last chunk even if it is not equal to the tile size tile_size = 15 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, ), mode='irregular') expected_split = [ self.data[i:i + tile_size] for i in range(0, self.n_elements, tile_size) ] calculated_split = [t for _, t in tiler(self.data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split)
def test_wrap_mode(self): # Wrap mode pads the tile with the wrap of the vector along the axis tile_size = 15 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, ), mode='wrap') expected_split = [ self.data[i:i + tile_size] for i in range(0, self.n_elements, tile_size) ] expected_split[-1] = np.pad(expected_split[-1], (0, tile_size - len(expected_split[-1])), mode='wrap') calculated_split = [t for _, t in tiler(self.data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split)
def test_reflect_mode(self): # Reflect mode pads with reflected values along the axis tile_size = 15 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, ), mode='reflect') expected_split = [ self.data[i:i + tile_size] for i in range(0, self.n_elements, tile_size) ] expected_split[-1] = np.pad(expected_split[-1], (0, tile_size - len(expected_split[-1])), mode='reflect') calculated_split = [t for _, t in tiler(self.data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split)
def test_edge_mode(self): # Edge mode pads with the edge values of data tile_size = 15 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, ), mode='edge') expected_split = [ self.data[i:i + tile_size] for i in range(0, self.n_elements, tile_size) ] expected_split[-1] = np.pad(expected_split[-1], (0, tile_size - len(expected_split[-1])), mode='edge') calculated_split = [t for _, t in tiler(self.data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split)
def test_generate_window(self): tiler = Tiler(data_shape=self.data.shape, tile_shape=(10, )) with self.assertRaises(ValueError): Merger(tiler=tiler, window='unsupported_window') with self.assertRaises(ValueError): Merger(tiler=tiler, window=np.zeros((10, 10))) with self.assertRaises(ValueError): Merger(tiler=tiler, window=10) window = np.zeros((10, )) window[1:10] = 1 merger = Merger(tiler=tiler, window=window) for t_id, t in tiler(self.data): merger.add(t_id, t) np.testing.assert_equal(merger.merge(), [i if i % 10 else 0 for i in range(100)])
def xmlrpc_render_cell(self, data): tiler = Tiler(self.config) tiler.cell_list = data return tiler.process_queue()
parser = argparse.ArgumentParser() parser.add_argument('slidepath', help='Path to .tif file') args = parser.parse_args() print(json.dumps({'initializing': args.slidepath})) start = time.time() tile_processor_pool = TileProcessorPool(workers=PROCESSOR_WORKERS) tile_processor_pool.start() tiler = Tiler(slidepath=args.slidepath, basename=TMP_DIR, format=FORMAT, tile_size=TILE_SIZE, overlap=OVERLAP, limit_bounds=True, workers=TILER_WORKERS, tile_processor_queue=tile_processor_pool.get_queue()) tiler.run() results = tile_processor_pool.gather_results() print(json.dumps({'tilingComplete': args.slidepath})) total_points_found, hpf_centers, hpf_points = find_hpfs(results) hpfs = list(zip(hpf_centers, hpf_points)) basename = os.path.basename(args.slidepath) with OpenSlide(args.slidepath) as slide: hpf_data = visualize(slide,
def test_callable_data(self): def fn(*x): raise ValueError(x) # 1D test tiler = Tiler(data_shape=(100, ), tile_shape=(10, )) for i in range(tiler.n_tiles): with self.assertRaises(ValueError) as cm: tiler.get_tile(fn, i) np.testing.assert_equal( cm.exception.args[0], (*tiler.get_tile_bbox_position(i)[0], *tiler.tile_shape)) # 2D test tiler = Tiler(data_shape=(100, 100), tile_shape=(10, 20)) for i in range(tiler.n_tiles): with self.assertRaises(ValueError) as cm: tiler.get_tile(fn, i) np.testing.assert_equal( cm.exception.args[0], (*tiler.get_tile_bbox_position(i)[0], *tiler.tile_shape)) # 3D test tiler = Tiler(data_shape=(100, 100, 100), tile_shape=(10, 20, 50)) for i in range(tiler.n_tiles): with self.assertRaises(ValueError) as cm: tiler.get_tile(fn, i) np.testing.assert_equal( cm.exception.args[0], (*tiler.get_tile_bbox_position(i)[0], *tiler.tile_shape)) # channel dimension test tiler = Tiler(data_shape=(100, 100, 3), tile_shape=(10, 20, 3), channel_dimension=2) for i in range(tiler.n_tiles): with self.assertRaises(ValueError) as cm: tiler.get_tile(fn, i) np.testing.assert_equal( cm.exception.args[0], (*tiler.get_tile_bbox_position(i, with_channel_dim=True)[0], *tiler.tile_shape))
def test_tile_bbox_position(self): tile_size = 10 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, )) tiler2 = Tiler(data_shape=(3, ) + self.data.shape, tile_shape=( 3, tile_size, ), channel_dimension=0) with self.assertRaises(IndexError): tiler.get_tile_bbox_position(-1) with self.assertRaises(IndexError): tiler.get_tile_bbox_position(len(tiler)) tile_id = 0 np.testing.assert_equal(([0], [10]), tiler.get_tile_bbox_position(tile_id)) np.testing.assert_equal(([0], [10]), tiler.get_tile_bbox_position(tile_id, True)) np.testing.assert_equal(([0], [10]), tiler2.get_tile_bbox_position(tile_id)) np.testing.assert_equal(([0, 0], [3, 10]), tiler2.get_tile_bbox_position(tile_id, True)) tile_id = len(tiler) - 1 np.testing.assert_equal(([90], [100]), tiler.get_tile_bbox_position(tile_id)) np.testing.assert_equal(([90], [100]), tiler.get_tile_bbox_position(tile_id, True)) np.testing.assert_equal(([90], [100]), tiler2.get_tile_bbox_position(tile_id)) np.testing.assert_equal(([0, 90], [3, 100]), tiler2.get_tile_bbox_position(tile_id, True))
def test_mosaic_shape(self): tile_size = 10 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, )) tiler2 = Tiler(data_shape=(3, ) + self.data.shape, tile_shape=( 3, tile_size, ), channel_dimension=0) tiler3 = Tiler(data_shape=(9, ) + self.data.shape, tile_shape=( 3, tile_size, ), channel_dimension=0) tiler4 = Tiler(data_shape=(9, ) + self.data.shape, tile_shape=( 3, tile_size, )) np.testing.assert_equal([10], tiler.get_mosaic_shape()) np.testing.assert_equal([10], tiler.get_mosaic_shape(with_channel_dim=True)) np.testing.assert_equal([10], tiler2.get_mosaic_shape()) np.testing.assert_equal([1, 10], tiler2.get_mosaic_shape(with_channel_dim=True)) np.testing.assert_equal([10], tiler3.get_mosaic_shape()) np.testing.assert_equal([1, 10], tiler3.get_mosaic_shape(with_channel_dim=True)) np.testing.assert_equal([3, 10], tiler4.get_mosaic_shape()) np.testing.assert_equal([3, 10], tiler4.get_mosaic_shape(with_channel_dim=True))
def wrapped_f(*args): config.col_count = cols config.row_count = rows f(*args, Tiler())
# Example "checkerboard"-like volume with some variation for visualization # https://stackoverflow.com/a/51715491 volume = (np.indices((150, 462, 462)).sum(axis=0) % 50).astype(np.float32) volume[:75] *= np.linspace(3, 10, 75)[:, None, None] volume[75:] *= np.linspace(10, 3, 75)[:, None, None] # Let's assume we want to use tiles of size 48x48x48 and only the middle 20x20x20 for the final image # That means we need to pad the image by 14 from each side # To extrapolate missing context let's use reflect mode padded_volume = np.pad(volume, 14, mode='reflect') # Specifying tiling # The overlap should be 28 voxels tiler = Tiler(data_shape=padded_volume.shape, tile_shape=(48, 48, 48), overlap=(28, 28, 28)) # Window function for merging window = np.zeros((48, 48, 48)) window[14:-14, 14:-14, 14:-14] = 1 # Specifying merging merger = Merger(tiler=tiler, window=window) # Let's define a function that will be applied to each tile # For this example, let's black out the sides that should be "cropped" by window function # as a way to confirm that only the middle parts are being merged def process(patch: np.ndarray) -> np.ndarray: patch[:14, :, :] = 0 patch[-14:, :, :] = 0
def test_get_tile(self): tile_size = 10 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, )) with self.assertRaises(IndexError): tiler.get_tile(self.data, len(tiler)) with self.assertRaises(IndexError): tiler.get_tile(self.data, -1) # copy test t = tiler.get_tile(self.data, 0, copy_data=True) t[9] = 0 np.testing.assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], tiler.get_tile(self.data, 0)) np.testing.assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 0], t) t = tiler.get_tile(self.data, 0, copy_data=False) t[9] = 0 np.testing.assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 0], tiler.get_tile(self.data, 0)) np.testing.assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 0], t) t[9] = 9 # test callable data fn = lambda x, w: self.data[x:x + w] t = tiler.get_tile(fn, 0) np.testing.assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], t) t = tiler.get_tile(fn, 1) np.testing.assert_equal([10, 11, 12, 13, 14, 15, 16, 17, 18, 19], t)
channels = [segment_channel, nuclear_channel] model = models.Cellpose(gpu=use_GPU, model_type=model_type) # Read files, preprocess, and load into array for cellpose print(f'Reading image {str(filename)}') reader = bioformats.ImageReader(str(filename)) def reader_func(*args) -> np.ndarray: X, Y, W, H = args[0], args[1], args[3], args[4] return reader.read(XYWH=(X, Y, W, H)) # type: ignore sizeX, sizeY, sizeC = (reader.rdr.getSizeX(), reader.rdr.getSizeY(), reader.rdr.getSizeC()) tiler = Tiler((sizeX, sizeY, sizeC), (tile_size, tile_size, sizeC), overlap=0.05) def preprocess(img): img = cv2.resize(img, (0, 0), fx=1/downsample, fy=1/downsample) img = cv2.medianBlur(img, 3) return img print('Loading and processing tiles') imgs = [] for i, img in tqdm(tiler.iterate(reader_func), total=len(tiler)): imgs.append(preprocess(img)) masks, flows, styles, diams = model.eval( imgs, diameter=diameter, channels=channels)
def test_tile_mosaic_position(self): tile_size = 10 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, )) tiler2 = Tiler(data_shape=(3, ) + self.data.shape, tile_shape=( 3, tile_size, ), channel_dimension=0) tile_id = 0 np.testing.assert_equal([0], tiler.get_tile_mosaic_position(tile_id)) np.testing.assert_equal([0], tiler.get_tile_mosaic_position( tile_id, with_channel_dim=True)) np.testing.assert_equal([0], tiler2.get_tile_mosaic_position(tile_id)) np.testing.assert_equal([0, 0], tiler2.get_tile_mosaic_position( tile_id, with_channel_dim=True)) tile_id = len(tiler) - 1 np.testing.assert_equal([9], tiler.get_tile_mosaic_position(tile_id)) np.testing.assert_equal([9], tiler.get_tile_mosaic_position( tile_id, with_channel_dim=True)) np.testing.assert_equal([9], tiler2.get_tile_mosaic_position(tile_id)) np.testing.assert_equal([0, 9], tiler2.get_tile_mosaic_position( tile_id, with_channel_dim=True)) with self.assertRaises(IndexError): tiler.get_tile_mosaic_position(-1) with self.assertRaises(IndexError): tiler.get_tile_mosaic_position(len(tiler))
from tiler import Tiler, Merger # Loading image # Photo by Christian Holzinger on Unsplash: https://unsplash.com/photos/CUY_YHhCFl4 image = np.array(Image.open('example_image.jpg')) # 1280x1920x3 # Padding image # Overlap tile strategy assumes we only use the small, non-overlapping, middle part of tile. # Assuming we want tiles of size 128x128 and we want to only use middle 64x64, # we should pad the image by 32 from each side, using reflect mode padded_image = np.pad(image, ((32, 32), (32, 32), (0, 0)), mode='reflect') # Specifying tiling parameters # The overlap should be 0.5, 64 or explicitly (64, 64, 0) tiler = Tiler(data_shape=padded_image.shape, tile_shape=(128, 128, 3), overlap=(64, 64, 0), channel_dimension=2) # Specifying merging parameters # You can define overlap-tile window explicitly, i.e. # window = np.zeros((128, 128, 3)) # window[32:-32, 32:-32, :] = 1 # merger = Merger(tiler=tiler, window=window) # or you can use overlap-tile window which will do that automatically based on tiler.overlap merger = Merger(tiler=tiler, window='overlap-tile') # Let's define a function that will be applied to each tile def process(patch: np.ndarray, sanity_check: bool = True) -> np.ndarray: # One example can be a sanity check
def test_overlap(self): # Case 1 # If overlap is an integer, the same overlap should be applied in each dimension tile_size = 10 overlap = 5 tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, ), overlap=overlap) expected_split = [[i for i in range(j, j + tile_size)] for j in range(0, self.n_elements - overlap, tile_size - overlap)] calculated_split = [t for _, t in tiler(self.data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split) # Case 2 # If overlap is a float, compute the actual number tile_size = 10 overlap = 0.5 el_overlap = int(tile_size * overlap) tiler = Tiler(data_shape=self.data.shape, tile_shape=(tile_size, ), overlap=overlap) expected_split = [[i for i in range(j, j + tile_size)] for j in range(0, self.n_elements - el_overlap, tile_size - el_overlap)] calculated_split = [t for _, t in tiler(self.data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split) # Case 3 # Overlap is provided as tuple or list # Let's try a slightly more complicated test case with a channel dimension tile_size = 10 data = np.vstack((self.data, self.data * 2, self.data * 3)) overlap = ( 0, 5, ) tiler = Tiler(data_shape=data.shape, tile_shape=( 3, tile_size, ), overlap=overlap) expected_split = [[[i for i in range(j, j + tile_size)], [i * 2 for i in range(j, j + tile_size)], [i * 3 for i in range(j, j + tile_size)]] for j in range(0, self.n_elements - overlap[1], tile_size - overlap[1])] calculated_split = [t for _, t in tiler(data)] self.assertEqual(len(tiler), len(expected_split)) np.testing.assert_equal(expected_split, calculated_split)