Skip to content

Commit

Permalink
Fixed simple image generator and improve speed
Browse files Browse the repository at this point in the history
  • Loading branch information
folterj committed Dec 3, 2023
1 parent b7b61a9 commit df2e927
Showing 1 changed file with 37 additions and 28 deletions.
65 changes: 37 additions & 28 deletions OmeSliCC/ImageGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,69 +103,78 @@ def get_tiles(self, tile_size, dtype=np.uint8):


class SimpleImageGenerator:
def __init__(self, size, seed=None):
def __init__(self, size, tile_size, dtype=np.uint8, seed=None):
self.size = size
self.tile_size = tile_size
self.dtype = dtype

if seed is not None:
np.random.seed(seed)

self.color_ranges = [
[(0, 0, 0), (1, 0, 0)],
[(0, 0, 0), (0, 1, 0)],
[(0, 0, 0), (0, 0, 1)],
]
self.color_value_table = [np.sin(np.divide(range(dim), dim, dtype=np.float32) * np.pi)
for dim in np.flip(size)]

# self.noise = np.random.random(size=shape) - 0.5 # uniform
self.noise = np.random.normal(loc=0, scale=0.1, size=np.flip(tile_size)) # gaussian

def calc_value(self, *args):
def calc_color(self, *args):
channels = []
channel = None
for index, value in enumerate(reversed(args)):
channel = (value + self.range0[index]) / self.size[index]
#channel = np.sin((value + self.range0[index]) / self.size[index] * np.pi)
channel = self.color_value_table[index][value + self.range0[index]]
channels.append(channel)
while len(channels) < 3:
channels.append(channel)
return np.stack(channels, axis=-1)

def get_tiles(self, tile_size, dtype=np.uint8):
def get_tiles(self):
if np.dtype(dtype).kind != 'f':
max_val = 2 ** (8 * np.dtype(dtype).itemsize) - 1
else:
max_val = 1
ranges = np.flip(np.ceil(np.divide(self.size, tile_size)).astype(int))
ranges = np.flip(np.ceil(np.divide(self.size, self.tile_size)).astype(int))
# flip: cycle over indices in x, y, z order using range = [z, y, x]
for indices in tqdm(list(np.ndindex(tuple(ranges)))):
self.range0 = np.flip(indices) * tile_size
self.range1 = np.min([self.range0 + tile_size, size], 0)
self.range1 = np.min([self.range0 + self.tile_size, self.size], 0)
shape = list(reversed(self.range1 - self.range0))

tile = np.fromfunction(self.calc_value, shape, dtype=np.float32)

#noise = np.random.random(size=shape) - 0.5 # uniform
noise = np.random.normal(loc=0, scale=0.1, size=shape) # gaussian
tile = np.fromfunction(self.calc_color, shape, dtype=int)

# apply noise to each channel separately
for channeli in range(3):
tile[..., channeli] = np.clip(tile[..., channeli] + noise, 0, 1)
tile[..., channeli] = np.clip(tile[..., channeli] + self.noise, 0, 1)

if np.dtype(dtype).kind != 'f':
tile *= max_val

# tile in (z,),y,x,c
yield tile.astype(dtype)
# TODO: wrap into dask array?


def save_tiff(filename, data, shape=None, dtype=None, tile_size=None, ome=False):
tifffile.imwrite(filename, data, shape=shape, dtype=dtype, tile=tile_size, ome=ome)
def save_tiff(filename, data, shape=None, dtype=None, tile_size=None, bigtiff=None, ome=False, compression=None):
if bigtiff is None:
if shape is not None and dtype is not None:
datasize = np.prod(shape, dtype=np.uint64) * np.dtype(dtype).itemsize
else:
datasize = data.size * data.itemsize
bigtiff = (datasize > 2 ** 32 - 2 ** 25 and not compression)
tifffile.imwrite(filename, data, shape=shape, dtype=dtype, tile=tile_size, bigtiff=bigtiff, ome=ome,
compression=compression)


def render_image(data, shape, dtype):
#for slice1, tile in tqdm(data):
# image[slice1] = tile

image = np.zeros(np.prod(shape, dtype=np.uint64), dtype=dtype)
position = np.uint64(0)
image = np.zeros(shape, dtype=dtype)
position = np.array([0] * len(shape))
for tile in data:
tshape = np.prod(tile.shape, dtype=np.uint64)
image[position: position + tshape] = tile.flatten()
position += tshape
image[position: position + tile.shape] = tile
position += tile.shape
# TODO: increase/carry-over (x,) y, z
image = image.reshape(shape)

if len(shape) <= 3 and shape[-1] <= 4:
Expand All @@ -182,8 +191,8 @@ def show_image(image):

if __name__ == '__main__':
# (tile) size in x,y(,z)
size = 1024, 1024, 1024
tile_size = 1024, 1024, 1
size = 2048, 2048, 2048
tile_size = 2048, 2048, 1
path = 'D:/slides/test.tiff'
dtype = np.uint8
#nscales = 2
Expand All @@ -194,12 +203,12 @@ def show_image(image):

print('init')
#image_generator = ImageGenerator(size, nscales, seed)
image_generator = SimpleImageGenerator(size, seed)
image_generator = SimpleImageGenerator(size, tile_size, dtype, seed)
print('init done')

data = image_generator.get_tiles(tile_size, dtype)
data = image_generator.get_tiles()
save_tiff(path, data, shape, dtype, tile_size=tile_shape, ome=True)
print('save done')

data = image_generator.get_tiles(tile_size, dtype)
data = image_generator.get_tiles()
render_image(data, shape, dtype)

0 comments on commit df2e927

Please sign in to comment.