def img2xy(self, ds_name, img_path, gal_path, gpr_path, row_inc, col_inc, scale, h_flip, v_flip, blur, noise, augment=0, cut_pp=None): if ds_name in self.gal_cache: gal = self.gal_cache[ds_name] else: gal = make_fake_gal( Gpr(gpr_path)) if gal_path == '' else Gal(gal_path) self.gal_cache[ds_name] = gal if img_path in self.img_cache: idxs, imgs, df, scales = self.img_cache[img_path] else: idxs, imgs, df, scales = self.img2x( img_path, gal, Gpr(gpr_path)) # imgs: (N, 1, h, w) self.img_cache[img_path] = idxs, imgs, df, scales if (imgs is None) or (df is None): print(f'{img_path} failed.') return None, None, None, None h, w = imgs.shape[-2], imgs.shape[-1] xs, ys, isori = [], [], [] for (img_path, b, c), img, block_df in zip(idxs, imgs, df): nrows = gal.header[f'Block{b}'][Gal.N_ROWS] ncols = gal.header[f'Block{b}'][Gal.N_COLS] kpts = KeypointsOnImage([ Keypoint(x=block_df.loc[1, 1]['X'], y=block_df.loc[1, 1]['Y']), Keypoint(x=block_df.loc[nrows, 1]['X'], y=block_df.loc[nrows, 1]['Y']), Keypoint(x=block_df.loc[nrows, ncols]['X'], y=block_df.loc[nrows, ncols]['Y']), Keypoint(x=block_df.loc[1, ncols]['X'], y=block_df.loc[1, ncols]['Y']), ], shape=(h, w)) # bsa bsa = BlockSizeAugmentor((nrows, ncols), cut_pp) img_ = [] kpts_ = kpts.copy() for im in img: im, kpts, _ = bsa.augment(im, kpts_.to_xy_array(), row_inc, col_inc) img_.append(im) img = np.stack(img_).astype('uint8') coord = self.to_Lcoord(kpts.to_xy_array()) if self.check_out_of_bounds(img.shape[1:], coord): continue img = np.moveaxis(img, 0, -1) # (c, h, w) -> (h, w, c) # h_flip if h_flip: aug_func = aug.HorizontalFlip(1) img, kpts = aug_func(image=img, keypoints=kpts) # v_flip if v_flip: aug_func = aug.VerticalFlip(1) img, kpts = aug_func(image=img, keypoints=kpts) # scale if scale != 1: aug_func = aug.Affine(scale=scale, mode='wrap') img, kpts = aug_func(image=img, keypoints=kpts) if self.check_out_of_bounds(img.shape[:2], kpts.to_xy_array()): continue # blur if blur != 0: aug_func = aug.GaussianBlur(sigma=blur) img, kpts = aug_func(image=img, keypoints=kpts) # noise if noise != 0: aug_func = aug.AdditiveGaussianNoise(scale=noise) img, kpts = aug_func(image=img, keypoints=kpts) img = np.moveaxis(img, -1, 0) # (h, w, c) -> (c, h, w) coord = self.to_Lcoord(kpts.to_xy_array()) if self.check_out_of_bounds(img.shape[1:], coord): continue xs.append(img) ys.append(coord.flatten()) isori.append(True) # augment if augment >= 1: augxs, augys, fail_count = [], [], 0 while len(augxs) < augment: img_aug, coord = self.run_aug(img, kpts) if fail_count > 5: return None, None, None, None if img_aug is None: fail_count += 1 continue augxs.append(img_aug) augys.append(coord.flatten()) xs.extend(augxs) ys.extend(augys) isori.extend([False] * len(augxs)) elif np.random.rand() < augment: img_aug, coord = self.run_aug(img, kpts) if img_aug is not None: xs.append(img_aug) ys.append(coord.flatten()) isori.append(False) if len(xs) <= 0: return None, None, None, None return np.stack(xs) / 255, np.stack(ys), np.stack(isori), ( bsa.row_cut_pp, bsa.col_cut_pp)
def img2xy(self, img_path, gal_path, gpr_path, augment=0, bsa_args: dict = None, blocks=None, keep_ori=True): ''' Single img file to xys for all blocks and channels args: blocks: If None, get all blocks in img. If given list / set, get only the blocks in the list ys: top left, bottom left, bottom right XYs of a block (L shape) (relative to window coords) shape ( #blocks*2, 6 ) is_ori (1D array): True : sample is original data False: sample is augmented data ''' gal = make_fake_gal(Gpr(gpr_path)) if gal_path == '' else Gal(gal_path) idxs, imgs, df, scales = super().img2x( img_path, gal, Gpr(gpr_path)) # imgs: (N, 1, h, w) if (imgs is None) or (df is None): return None, None h, w = imgs.shape[2], imgs.shape[3] xs, ys, is_ori = [], [], [] for (img_path, b, c), img, block_df in zip(idxs, imgs, df): if (blocks is not None) and not (b in blocks): continue nrows = gal.header[f'Block{b}'][Gal.N_ROWS] ncols = gal.header[f'Block{b}'][Gal.N_COLS] kpts = KeypointsOnImage([ Keypoint(x=block_df.loc[1, 1]['X'], y=block_df.loc[1, 1]['Y']), Keypoint(x=block_df.loc[nrows, 1]['X'], y=block_df.loc[nrows, 1]['Y']), Keypoint(x=block_df.loc[nrows, ncols]['X'], y=block_df.loc[nrows, ncols]['Y']), Keypoint(x=block_df.loc[1, ncols]['X'], y=block_df.loc[1, ncols]['Y']), ], shape=(h, w)) if keep_ori: xs.append(img) coord = self.to_Lcoord(kpts.to_xy_array()) ys.append(coord.flatten()) is_ori.append(True) if bsa_args is not None: augxs, augys = [], [] while len(augxs) < bsa_args['n']: row_inc = np.random.choice(bsa_args['row_inc_choice']) col_inc = np.random.choice(bsa_args['col_inc_choice']) bsa = BlockSizeAugmentor((nrows, ncols)) img_ = [] kpts_ = kpts.copy() for im in img: im, kpts, _ = bsa.augment(im, kpts_.to_xy_array(), row_inc, col_inc) img_.append(im) img = np.stack(img_).astype('uint8') coord = self.to_Lcoord(kpts.to_xy_array()) if self.check_out_of_bounds(img.shape[1:], coord): continue augxs.append(img) augys.append(coord.flatten()) xs.extend(augxs) ys.extend(augys) is_ori.extend([False] * len(augxs)) if augment >= 1: augxs, augys = [], [] while len(augxs) < augment: img_aug, coord = self.run_aug(img, kpts) if img_aug is None: continue augxs.append(img_aug) augys.append(coord.flatten()) xs.extend(augxs) ys.extend(augys) is_ori.extend([False] * len(augxs)) elif np.random.rand() < augment: img_aug, coord = self.run_aug(img, kpts) if img_aug is None: continue xs.append(img_aug) ys.append(coord.flatten()) is_ori.append(False) return np.stack(xs) / 255, np.stack(ys), np.array(is_ori)