def __getitem__(self, _): image, annot, _ = load_train_image_and_annot(self.dataset_dir, self.train_annot_dir) tile_pad = (self.in_w - self.out_w) // 2 # ensures each pixel is sampled with equal chance im_pad_w = self.out_w + tile_pad padded_w = image.shape[1] + (im_pad_w * 2) padded_h = image.shape[0] + (im_pad_w * 2) padded_im = im_utils.pad(image, im_pad_w) # This speeds up the padding. annot = annot[:, :, :2] padded_annot = im_utils.pad(annot, im_pad_w) right_lim = padded_w - self.in_w bottom_lim = padded_h - self.in_w # TODO: # Images with less annoations will still give the same number of # tiles in the training procedure as images with more annotation. # Further empirical investigation into effects of # instance selection required are required. while True: x_in = math.floor(random.random() * right_lim) y_in = math.floor(random.random() * bottom_lim) annot_tile = padded_annot[y_in:y_in + self.in_w, x_in:x_in + self.in_w] if np.sum(annot_tile) > 0: break im_tile = padded_im[y_in:y_in + self.in_w, x_in:x_in + self.in_w] assert annot_tile.shape == (self.in_w, self.in_w, 2), (f" shape is {annot_tile.shape}") assert im_tile.shape == (self.in_w, self.in_w, 3), (f" shape is {im_tile.shape}") im_tile = img_as_float32(im_tile) im_tile = im_utils.normalize_tile(im_tile) im_tile, annot_tile = self.augmentor.transform(im_tile, annot_tile) im_tile = im_utils.normalize_tile(im_tile) foreground = np.array(annot_tile)[:, :, 0] background = np.array(annot_tile)[:, :, 1] # Annotion is cropped post augmentation to ensure # elastic grid doesn't remove the edges. foreground = foreground[tile_pad:-tile_pad, tile_pad:-tile_pad] background = background[tile_pad:-tile_pad, tile_pad:-tile_pad] # mask specified pixels of annotation which are defined mask = foreground + background mask = mask.astype(np.float32) mask = torch.from_numpy(mask) foreground = foreground.astype(np.int64) foreground = torch.from_numpy(foreground) im_tile = im_tile.astype(np.float32) im_tile = np.moveaxis(im_tile, -1, 0) im_tile = torch.from_numpy(im_tile) return im_tile, foreground, mask
def transform_annotation(image, def_map, padding=60): image = np.array(image) image = im_utils.pad(image, padding, mode='reflect') if len(image.shape) > 2: image = image.reshape(image.shape[:2]) shape = image.shape out = map_coordinates(image[:, :], def_map, order=1).reshape(shape) out = out[padding:-padding, padding:-padding] out = np.round(out).astype(np.int64) return out
def transform_image(image, def_map, padding=60, channels=3): """ conditional transform, depending on presence of values in each channel """ indices = def_map image = np.array(image) image = im_utils.pad(image, padding, mode='reflect') # We presume there are 3 channels. Checking shape is slow. for i in range(channels): if np.sum(image[:, :, i]): image[:, :, i] = map_coordinates(image[:, :, i], indices, order=1) image = image[padding:-padding, padding:-padding] return image
def transform_photo(image, def_map, padding=60): indices = def_map image = np.array(image) image = im_utils.pad(image, padding, mode='reflect') out_r = map_coordinates(image[:, :, 0], indices, order=1) out_g = map_coordinates(image[:, :, 1], indices, order=1) out_b = map_coordinates(image[:, :, 2], indices, order=1) image[:, :, 0] = out_r image[:, :, 1] = out_g image[:, :, 2] = out_b image = image[padding:-padding, padding:-padding] return image