def _get_patch_for_card(self, card): patch = self.patches.get(card, None) if patch is None: colour, shape, digit = card f = os.path.join(os.path.dirname(dps.__file__), "datasets/shapes", "{}.png".format(shape)) image = imageio.imread(f) image = resize_image(image[..., 3], self.patch_shape) image = self._colourize(image, colour) shape_colour = image[:, :, :3] shape_alpha = image[:, :, 3:4] / 255. f = os.path.join(os.path.dirname(dps.__file__), "datasets/digits", "{}.png".format(digit)) digit_image = imageio.imread(f) digit_image = resize_image(digit_image[..., 3], self.patch_shape) digit_image = self._colourize(digit_image, self.digit_colour) digit_colour = digit_image[:, :, :3] digit_alpha = digit_image[:, :, 3:4] / 255. image_rgb = digit_alpha * digit_colour + (1-digit_alpha) * shape_colour image_alpha = (np.clip(digit_alpha + shape_alpha, 0, 1) * 255).astype(np.uint8) patch = self.patches[card] = np.concatenate([image_rgb, image_alpha], axis=2) return patch
def get_appearance(self): key = (self.color, self.h, self.w) image = Entity.images.get(key, None) if image is None: color_array = np.array(to_rgb(self.color))[None, None, :] image = Entity.images[key] = np.tile(color_array, (self.h, self.w, 1)) key = (self.appearance, self.h, self.w) mask = Entity.masks.get(key, None) if mask is None: f = os.path.join(os.path.dirname(dps.__file__), "shapes", "{}.png".format(self.appearance)) mask = imageio.imread(f) mask = mask[:, :, 3:] mask = resize_image(mask, (self.h, self.w)) mask = Entity.masks[key] = mask / 255. noise_res = getattr(self, "noise_res", None) if noise_res is not None: noise = generate_perlin_noise_2d(self.shape, self.noise_res, normalize=True) mask = mask * noise[:, :, None] return image, mask
def compute_pixelwise_mode2(files, shape): data = [] for f in files[:10]: image = imageio.imread(os.path.join(f)) image = resize_image(image[:, :, :3], shape) data.extend(list(image.reshape(-1, 3))) data = np.random.permutation(data)[:10000] from sklearn import cluster n_clusters = 64 kmeans = cluster.KMeans(n_clusters=n_clusters) print("Clustering...") kmeans.fit(data) values = kmeans.cluster_centers_.squeeze()[:, None, None, :] counters = None print("Counting...") for f in files: image = imageio.imread(os.path.join(f)) image = resize_image(image[:, :, :3], shape) if counters is None: counters = np.array([ collections.Counter() for i in range(image.shape[0] * image.shape[1]) ]) counters = counters.reshape(image.shape[:2]) distances = np.linalg.norm(values - image[None, :, :, :], axis=3) indices = np.argmin(distances, axis=0) for i in range(image.shape[0]): for j in range(image.shape[1]): counters[i, j].update([indices[i, j]]) print("Computing mode...") mode_image = [[values[c.most_common(1)[0][0], 0, 0, :] for c in row] for row in counters] print("Done...") return np.array(mode_image).astype(image.dtype)
def _per_ep_callback(self, o, a, r): """ process one episode """ n_frames_per_video = self.n_frames * self.n_batches episode_length = len(a) # o is one step longer than a and r # Doesn't support averaging frames. n_frames_to_fetch = (n_frames_per_video - 1) * self.frame_skip + 1 max_start_idx = episode_length - n_frames_to_fetch + 1 if max_start_idx < 0: return indices = np.random.choice(max_start_idx + 1, size=self.n_samples_per_episode, replace=False) print("indices: ", indices) step = self.frame_skip for start in indices: if self._n_examples % 100 == 0: print("Processing example {}".format(self._n_examples)) end = start + n_frames_to_fetch _o = np.array(o[start:end:step]) _a = np.array(a[start:end:step]).flatten() _r = np.array(r[start:end:step]).flatten() assert len(_o) == n_frames_per_video assert len(_a) == n_frames_per_video assert len(_r) == n_frames_per_video if self.crop is not None: top, bot, left, right = self.crop _o = _o[:, top:bot, left:right, ...] if self.image_shape is not None and _o.shape[ 1:3] != self.image_shape: _o = np.array( [resize_image(img, self.image_shape) for img in _o]) if self.after_warp: _o = np.tile(_o, (1, 1, 1, 3)) self.fragments['o'].append(_o) self.fragments['a'].append(_a) self.fragments['r'].append(_r) self._n_examples += 1 if self._n_examples >= self.batch_size: print("Found maximum of {} examples, done.".format( self._n_examples)) return True
def make_patch(patch_shape, color, shape, importance): f = os.path.join(os.path.dirname(dps.__file__), "datasets/shapes", "{}.png".format(shape)) image = imageio.imread(f) image = resize_image(image[..., 3], patch_shape) image = _colorize(image, color) image = (image / 255.).astype('f') imp = np.maximum(importance * image[..., 3:4], 0.01) image = np.concatenate([image, imp], axis=2) return image
def _make(self): self.patches = {} for spec in self.shape_specs: shape, colour = spec.split(",") f = os.path.join(os.path.dirname(dps.__file__), "datasets/shapes", "{}.png".format(shape)) image = imageio.imread(f) image = resize_image(image[..., 3], self.patch_shape) image = self._colourize(image, colour) self.patches[spec] = image super(ShapesDataset, self)._make()
def compute_pixelwise_mean(files, shape): mean = None n_points = 0 for k, f in enumerate(files): if k % 100 == 0: print("Processing files {}".format(k)) image = imageio.imread(os.path.join(f)) image = resize_image(image[:, :, :3], shape) if mean is None: mean = image else: mean = (mean * n_points + image) / (n_points + 1) n_points += 1 return mean.astype(image.dtype)
def maybe_convert_emnist_shape(path, shape): """ Create a version of emnist on disk that is reshaped to the desired shape. Images are stored on disk as uint8. """ if shape == (28, 28): return shape_dir = os.path.join(path, 'emnist_{}_by_{}'.format(*shape)) if os.path.isdir(shape_dir): return emnist_dir = os.path.join(path, 'emnist') print("Converting (28, 28) EMNIST dataset to {}...".format(shape)) try: shutil.rmtree(shape_dir) except FileNotFoundError: pass os.makedirs(shape_dir, exist_ok=False) classes = ''.join([str(i) for i in range(10)] + [chr(i + ord('A')) for i in range(26)] + [chr(i + ord('a')) for i in range(26)]) for i, cls in enumerate(sorted(classes)): with gzip.open(os.path.join(emnist_dir, str(cls) + '.pklz'), 'rb') as f: _x = dill.load(f) new_x = [] for img in _x[:10]: img = resize_image(img, shape, preserve_range=True) new_x.append(img) print(cls) print(image_to_string(_x[0])) _x = np.array(new_x, dtype=_x.dtype) print(image_to_string(_x[0])) path_i = os.path.join(shape_dir, cls + '.pklz') with gzip.open(path_i, 'wb') as f: dill.dump(_x, f, protocol=dill.HIGHEST_PROTOCOL)
def _per_ep_callback(self, o, a, r): """ process one episode """ episode_length = len(a) # o is one step longer than a and r frame_size = (self.n_frames - 1) * self.frame_skip + 1 max_start_idx = episode_length - frame_size + 1 if max_start_idx <= self.max_samples_per_ep: indices = np.arange(max_start_idx) else: indices = np.random.choice(max_start_idx, size=self.max_samples_per_ep, replace=False) step = self.frame_skip for start in indices: if self._n_examples % 100 == 0: print("Processing example {}".format(self._n_examples)) end = start + frame_size _o = np.array(o[start:end:step]) _a = np.array(a[start:end:step]).flatten() _r = np.array(r[start:end:step]).flatten() assert len(_o) == self.n_frames assert len(_a) == self.n_frames assert len(_r) == self.n_frames if self.image_shape is not None and _o.shape[ 1:3] != self.image_shape: _o = np.array( [resize_image(img, self.image_shape) for img in _o]) if self.after_warp: _o = np.tile(_o, (1, 1, 1, 3)) self._write_example(image=_o, action=_a, reward=_r) self._n_examples += 1 if self._n_examples >= self.max_examples: print("Found maximum of {} examples, done.".format( self._n_examples)) return True
def load_backgrounds(background_names, shape=None): if isinstance(background_names, str): background_names = background_names.split() backgrounds_dir = os.path.join(cfg.data_dir, 'backgrounds') backgrounds = [] for name in background_names: f = os.path.join(backgrounds_dir, '{}.jpg'.format(name)) try: b = imageio.imread(f) except FileNotFoundError: f = os.path.join(backgrounds_dir, '{}.png'.format(name)) b = imageio.imread(f) if shape is not None and b.shape != shape: b = resize_image(b, shape) b = np.uint8(b) backgrounds.append(b) return backgrounds
def convert_emnist_and_store(path, new_image_shape): """ Images are stored on disk in float format. """ if new_image_shape == (28, 28): raise Exception("Original shape of EMNIST is (28, 28).") print( "Converting (28, 28) EMNIST dataset to {}...".format(new_image_shape)) emnist_dir = os.path.join(path, 'emnist') new_dir = os.path.join(path, 'emnist_{}_by_{}'.format(*new_image_shape)) try: shutil.rmtree(str(new_dir)) except FileNotFoundError: pass os.mkdir(new_dir) classes = ''.join([str(i) for i in range(10)] + [chr(i + ord('A')) for i in range(26)] + [chr(i + ord('a')) for i in range(26)]) for i, cls in enumerate(sorted(classes)): with gzip.open(os.path.join(emnist_dir, str(cls) + '.pklz'), 'rb') as f: _x = dill.load(f) new_x = [] for img in _x: img = resize_image(img, new_image_shape, preserve_range=False) new_x.append(img) print(cls) print(image_to_string(_x[0])) _x = np.array(new_x, dtype=_x.dtype) print(image_to_string(_x[0])) path_i = os.path.join(new_dir, cls + '.pklz') with gzip.open(path_i, 'wb') as f: dill.dump(_x, f, protocol=dill.HIGHEST_PROTOCOL)
def compute_pixelwise_mode(files, shape): counters = None for k, f in enumerate(files): if k % 100 == 0: print("Processing files {}".format(k)) image = imageio.imread(os.path.join(f)) image = resize_image(image[:, :, :3], shape) if counters is None: counters = np.array([ collections.Counter() for i in range(image.shape[0] * image.shape[1]) ]) counters = counters.reshape(image.shape[:2]) for i in range(image.shape[0]): for j in range(image.shape[1]): counters[i, j].update([tuple(image[i, j])]) mode_image = [[c.most_common(1)[0][0] for c in row] for row in counters] return np.array(mode_image).astype(image.dtype)
def load_emnist(classes, balance=False, include_blank=False, shape=None, n_examples=None, example_range=None, show=False, path=None): """ Load emnist data from disk by class. Elements of `classes` pick out which emnist classes to load, but different labels end up getting returned because most classifiers require that the labels be in range(len(classes)). We return a dictionary `class_map` which maps from elements of `classes` down to range(len(classes)). Pixel values of returned images are integers in the range 0-255, but stored as float32. Returned X array has shape (n_images,) + shape. Parameters ---------- path: str Path to data directory, assumed to contain a sub-directory called `emnist`. classes: list of character from the set (0-9, A-Z, a-z) Each character is the name of a class to load. balance: bool If True, will ensure that all classes are balanced by removing elements from classes that are larger than the minimu-size class. include_blank: bool If True, includes an additional class that consists of blank images. shape: (int, int) Shape of the images. n_examples: int Maximum number of examples returned. If not supplied, return all available data. example_range: pair of floats Pair of floats specifying, for each class, the range of examples that should be used. Each element of the pair is a number in (0, 1), and the second number should be larger. show: bool If True, prints out an image from each class. """ if path is None: path = cfg.data_dir maybe_download_emnist(path, shape=shape) emnist_dir = os.path.join(path, 'emnist') classes = list(classes) + [] needs_reshape = False if shape and shape != (28, 28): resized_dir = os.path.join(path, 'emnist_{}_by_{}'.format(*shape)) if _validate_emnist(resized_dir): emnist_dir = resized_dir else: needs_reshape = True if example_range is not None: assert 0.0 <= example_range[0] < example_range[1] <= 1.0 x, y = [], [] class_count = [] classes = sorted([str(s) for s in classes]) for i, cls in enumerate(classes): with gzip.open(os.path.join(emnist_dir, str(cls) + '.pklz'), 'rb') as f: _x = dill.load(f) if example_range is not None: low = int(example_range[0] * len(_x)) high = int(example_range[1] * len(_x)) _x = _x[low:high, ...] x.append(_x) y.extend([i] * _x.shape[0]) if show: print(cls) indices_to_show = np.random.choice(len(_x), size=100) for i in indices_to_show: print(image_to_string(_x[i])) class_count.append(_x.shape[0]) x = np.concatenate(x, axis=0) if include_blank: min_class_count = min(class_count) blanks = np.zeros((min_class_count, ) + x.shape[1:], dtype=np.uint8) x = np.concatenate((x, blanks), axis=0) blank_idx = len(classes) y.extend([blank_idx] * min_class_count) blank_symbol = ' ' classes.append(blank_symbol) y = np.array(y) if balance: min_class_count = min(class_count) keep_x, keep_y = [], [] for i, cls in enumerate(classes): keep_indices = np.nonzero(y == i)[0] keep_indices = keep_indices[:min_class_count] keep_x.append(x[keep_indices]) keep_y.append(y[keep_indices]) x = np.concatenate(keep_x, axis=0) y = np.concatenate(keep_y, axis=0) order = np.random.permutation(x.shape[0]) x = x[order] y = y[order] if n_examples: x = x[:n_examples] y = y[:n_examples] if needs_reshape: if x.shape[0] > 10000: warnings.warn( "Performing an online resize of a large number of images ({}), " "consider creating and storing the resized dataset.".format( x.shape[0])) x = [resize_image(img, shape) for img in x] x = np.uint8(x) if show: indices_to_show = np.random.choice(len(x), size=200) for i in indices_to_show: print(y[i]) print(image_to_string(x[i])) return x, y, classes
def _make(self): assert self.clevr_kind in "train val test".split() if self.has_annotations: sizes = ['large', 'small'] colors = [ 'gray', 'red', 'blue', 'green', 'brown', 'purple', 'cyan', 'yellow' ] materials = ['rubber', 'metal'] shapes = ['cube', 'sphere', 'cylinder'] self.class_names = [ ' '.join(lst) for lst in product(sizes, colors, materials, shapes) ] scene_file = os.path.join( cfg.data_dir, "CLEVR_v1.0/scenes/CLEVR_{}_scenes.json".format( self.clevr_kind)) with open(scene_file, 'r') as f: scenes = json.load(f)['scenes'] directory = os.path.join(cfg.data_dir, "CLEVR_v1.0/images", self.clevr_kind) files = os.listdir(directory) if self.example_range is not None: assert self.example_range[0] < self.example_range[1] files = [(f, self.get_idx_from_filename(f)) for f in files] files = [ f for f, idx in files if self.example_range[0] <= idx < self.example_range[1] ] files = np.random.choice(files, size=int(self.n_examples), replace=False) files = [os.path.join(directory, f) for f in files] background = None if self.clevr_background_mode == "mean": background = self.compute_pixelwise_mean(files[:5000], self.image_shape) elif self.clevr_background_mode == "median": background = self.compute_pixelwise_median(files[:5000], self.image_shape) elif self.clevr_background_mode == "mode": background = self.compute_pixelwise_mode(files[:5000], self.image_shape) # background = self.compute_pixelwise_mode2(files, self.image_shape) if background is not None: background = background.astype('uint8') for k, f in enumerate(files): if k % 100 == 0: print("Processing image {}".format(k)) image = imageio.imread(f) image = image[..., :3] # Get rid of alpha channel. if image.shape[:2] != self.image_shape: image = resize_image(image, self.image_shape) if self.has_annotations: idx = self.get_idx_from_filename(f) scene = scenes[idx] assert scene['image_filename'] == os.path.split(f)[1] annotations = self.extract_bounding_boxes(scene) else: annotations = [] self._write_example(image=image, annotations=annotations, label=0, background=background)
def load_omniglot( path, classes, include_blank=False, shape=None, one_hot=False, indices=None, show=False): """ Load omniglot data from disk by class. Elements of `classes` pick out which omniglot classes to load, but different labels end up getting returned because most classifiers require that the labels be in range(len(classes)). We return a dictionary `class_map` which maps from elements of `classes` down to range(len(classes)). Returned images are arrays of floats in the range 0-255. White text on black background (with 0 corresponding to black). Returned X array has shape (n_images,) + shape. Parameters ---------- path: str Path to data directory, assumed to contain a sub-directory called `omniglot`. classes: list of strings, each giving a class label Each character is the name of a class to load. balance: bool If True, will ensure that all classes are balanced by removing elements from classes that are larger than the minimu-size class. include_blank: bool If True, includes an additional class that consists of blank images. shape: (int, int) Shape of returned images. one_hot: bool If True, labels are one-hot vectors instead of integers. indices: list of int The image indices within the classes to include. For each class there are 20 images. show: bool If True, prints out an image from each class. """ omniglot_dir = os.path.join(path, 'omniglot') classes = list(classes)[:] if not indices: indices = list(range(20)) for idx in indices: assert 0 <= idx < 20 x, y = [], [] class_map, class_count = {}, {} for i, cls in enumerate(sorted(list(classes))): alphabet, character = cls.split(',') char_dir = os.path.join(omniglot_dir, alphabet, "character{:02d}".format(int(character))) files = os.listdir(char_dir) class_id = files[0].split("_")[0] for idx in indices: f = os.path.join(char_dir, "{}_{:02d}.png".format(class_id, idx + 1)) _x = imageio.imread(f) # Convert to white-on-black _x = 255. - _x if shape: _x = resize_image(_x, shape) x.append(_x) y.append(i) if show: print(cls) print(image_to_string(x[-1])) class_map[cls] = i class_count[cls] = len(indices) x = np.array(x, dtype=np.uint8) if include_blank: min_class_count = min(class_count.values()) blanks = np.zeros((min_class_count,) + shape, dtype=np.uint8) x = np.concatenate((x, blanks), axis=0) blank_idx = len(class_map) y.extend([blank_idx] * min_class_count) blank_symbol = ' ' class_map[blank_symbol] = blank_idx classes.append(blank_symbol) y = np.array(y) order = np.random.permutation(x.shape[0]) x = x[order] y = y[order] if one_hot: _y = np.zeros((y.shape[0], len(classes))).astype('f') _y[np.arange(y.shape[0]), y] = 1.0 y = _y return x, y, class_map
def _per_ep_callback(self, o, a, r): """ process one episode """ episode_length = len(a) # o is one step longer than a and r n_frames_to_fetch = (self.n_frames - 1) * self.frame_skip + 1 + int( self.average_frames) max_start_idx = episode_length - n_frames_to_fetch + 1 n_samples = int(np.ceil(self.sample_density * max_start_idx)) indices = np.random.choice(max_start_idx, size=n_samples, replace=False) step = self.frame_skip for start in indices: if self._n_examples % 100 == 0: print("Processing example {}".format(self._n_examples)) end = start + n_frames_to_fetch if self.average_frames: _o = np.array(o[start:end]) _o = np.maximum(_o[:-1], _o[1:]) # _o = (_o[:-1] + _o[1:]) / 2 _o = _o[::step].astype(o[0].dtype) _a = np.array(a[start + 1:end:step]).flatten() _r = np.array(r[start + 1:end:step]).flatten() else: _o = np.array(o[start:end:step]) _a = np.array(a[start:end:step]).flatten() _r = np.array(r[start:end:step]).flatten() assert len(_o) == self.n_frames assert len(_a) == self.n_frames assert len(_r) == self.n_frames if self.crop is not None: top, bot, left, right = self.crop _o = _o[:, top:bot, left:right, ...] if self.image_shape is not None and _o.shape[ 1:3] != self.image_shape: _o = np.array( [resize_image(img, self.image_shape) for img in _o]) if self.after_warp: _o = np.tile(_o, (1, 1, 1, 3)) if self.get_annotations: annotations = self._get_annotations(_o) else: annotations = [[] for i in range(self.n_frames)] self._write_example(image=_o, action=_a, reward=_r, annotations=annotations) self._n_examples += 1 if self._n_examples >= self.max_examples: print("Found maximum of {} examples, done.".format( self._n_examples)) return True
def _make(self): """ To handle both images and videos: * for each example, sample patch locations as well as velocities * want to make it so they they don't have to return velocities. can use *rest * in case velocities not return, use a velocity of 0. * go through all frames for the example, using an identical process to render each frame * if n_frames == 0, remove the frame dimension, so they really are just images. * assume a fixed background for the entire video, for now. """ if self.n_examples == 0: return np.zeros((0, ) + self.image_shape).astype('uint8'), np.zeros( (0, 1)).astype('i') # --- prepare colours --- colours = self.colours if colours is None: colours = [] if isinstance(colours, str): colours = colours.split() colour_map = mpl.colors.get_named_colors_mapping() self._colours = [] for c in colours: c = mpl.colors.to_rgb(colour_map[c]) c = np.array(c)[None, None, :] c = np.uint8(255. * c) self._colours.append(c) # --- prepare shapes --- self.draw_shape = self.draw_shape or self.image_shape self.draw_offset = self.draw_offset or (0, 0) draw_shape = self.draw_shape if self.depth is not None: draw_shape = draw_shape + (self.depth, ) # --- prepare backgrounds --- if self.backgrounds == "all": backgrounds = background_names() elif isinstance(self.backgrounds, str): backgrounds = self.backgrounds.split() else: backgrounds = self.backgrounds if backgrounds: if self.backgrounds_resize: backgrounds = load_backgrounds(backgrounds, draw_shape) else: backgrounds = load_backgrounds(backgrounds) background_colours = self.background_colours if isinstance(self.background_colours, str): background_colours = background_colours.split() _background_colours = [] for bc in background_colours: color = mpl.colors.to_rgb(bc) color = np.array(color)[None, None, :] color = np.uint8(255. * color) _background_colours.append(color) background_colours = _background_colours # --- start dataset creation --- for j in range(int(self.n_examples)): if j % 1000 == 0: print("Working on datapoint {}...".format(j)) # --- populate background --- if backgrounds: b_idx = np.random.randint(len(backgrounds)) background = backgrounds[b_idx] top = np.random.randint(background.shape[0] - draw_shape[0] + 1) left = np.random.randint(background.shape[1] - draw_shape[1] + 1) base_image = background[top:top + draw_shape[0], left:left + draw_shape[1], ...] + 0 elif background_colours: color = background_colours[np.random.randint( len(background_colours))] base_image = color * np.ones(draw_shape, 'uint8') else: base_image = np.zeros(draw_shape, 'uint8') # --- sample and populate patches --- locs, patches, patch_labels, image_label = self._sample_image() draw_offset = self.draw_offset images = [] annotations = [] for frame in range(max(self.n_frames, 1)): image = base_image.copy() for patch, loc in zip(patches, locs): if patch.shape[:2] != (loc.h, loc.w): patch = resize_image(patch, (loc.h, loc.w)) top = int(np.clip(loc.top, 0, image.shape[0])) bottom = int(np.clip(loc.bottom, 0, image.shape[0])) left = int(np.clip(loc.left, 0, image.shape[1])) right = int(np.clip(loc.right, 0, image.shape[1])) patch_top = top - int(loc.top) patch_bottom = bottom - int(loc.top) patch_left = left - int(loc.left) patch_right = right - int(loc.left) intensity = patch[patch_top:patch_bottom, patch_left:patch_right, :-1] alpha = patch[patch_top:patch_bottom, patch_left:patch_right, -1:].astype('f') / 255. current = image[top:bottom, left:right, ...] image[top:bottom, left:right, ...] = np.uint8(alpha * intensity + (1 - alpha) * current) # --- add distractors --- if self.n_distractors_per_image > 0: distractor_patches = self._sample_distractors() distractor_shapes = [ img.shape for img in distractor_patches ] distractor_locs = self._sample_patch_locations( distractor_shapes) for patch, loc in zip(distractor_patches, distractor_locs): if patch.shape[:2] != (loc.h, loc.w): anti_aliasing = patch.shape[ 0] < loc.h or patch.shape[1] < loc.w patch = resize_image(patch, (loc.h, loc.w)) intensity = patch[:, :, :-1] alpha = patch[:, :, -1:].astype('f') / 255. current = image[loc.top:loc.bottom, loc.left:loc.right, ...] image[loc.top:loc.bottom, loc.left:loc.right, ...] = (np.uint8(alpha * intensity + (1 - alpha) * current)) # --- possibly crop entire image --- if self.draw_shape != self.image_shape or draw_offset != (0, 0): image_shape = self.image_shape if self.depth is not None: image_shape = image_shape + (self.depth, ) draw_top = np.maximum(-draw_offset[0], 0) draw_left = np.maximum(-draw_offset[1], 0) draw_bottom = np.minimum( -draw_offset[0] + self.image_shape[0], self.draw_shape[0]) draw_right = np.minimum( -draw_offset[1] + self.image_shape[1], self.draw_shape[1]) image_top = np.maximum(draw_offset[0], 0) image_left = np.maximum(draw_offset[1], 0) image_bottom = np.minimum( draw_offset[0] + self.draw_shape[0], self.image_shape[0]) image_right = np.minimum( draw_offset[1] + self.draw_shape[1], self.image_shape[1]) _image = np.zeros(image_shape, 'uint8') _image[image_top:image_bottom, image_left:image_right, ...] = \ image[draw_top:draw_bottom, draw_left:draw_right, ...] image = _image _annotations = self._get_annotations(draw_offset, patches, locs, patch_labels) images.append(image) annotations.append(_annotations) for loc in locs: loc.update(image.shape) if self.n_frames == 0: images = images[0] annotations = annotations[0] self._write_example(image=images, annotations=annotations, label=image_label)