def picture_argument(image_input, image_gt, rotate, zoom): """ 对输入的病理切片,进行旋转、缩放操作的图像增强,并生成经过同样旋转、缩放操作的标注区域 :param image_input 输入的病理切片图像 :param image_gt 输入的病例切片癌症标注区域图像 :param rotate 对图像进行旋转的正负角度范围 :param zoom 对图像进行缩放操作的放大缩小百分比 :return image_input,image_gt 旋转、缩放后的病理切片图像,以及对应的癌症区域标注 """ theta = np.pi / 180 * np.random.uniform(-rotate, rotate) rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) transform_matrix = rotation_matrix zx, zy = np.random.uniform(1 - zoom, 1 + zoom, 2) zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]]) transform_matrix = np.dot(transform_matrix, zoom_matrix) h, w = image_input.shape[0], image_input.shape[1] transform_matrix = transform_matrix_offset_center(transform_matrix, h, w) image_input = apply_transform(image_input, transform_matrix, 2, fill_mode="constant", cval=255) image_gt = apply_transform(image_gt, transform_matrix, 2, fill_mode="constant", cval=False) return image_input, image_gt
def rotate(x, y=None, rotate_limit=0, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.): theta = np.pi / 180 * np.random.uniform(-1 * rotate_limit, rotate_limit) # 逆时针旋转角度 rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) h, w = x.shape[row_axis], x.shape[col_axis] transform_matrix = image.transform_matrix_offset_center(rotation_matrix, h, w) x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) if y is not None: all_x = np.concatenate((y[0:5], y[10:15], y[20:25], y[30:35])) all_y = np.concatenate((y[5:10], y[15:20], y[25:30], y[35:40])) all_x = all_x.reshape((1, -1)) all_y = all_y.reshape((1, -1)) all_xy1 = np.concatenate((all_x, all_y, np.ones((1, all_x.shape[1]))), axis=0) y_1 = np.dot(transform_matrix, all_xy1)[0:-1, :] y[0:5] = y_1[0, 0:5] y[5:10] = y_1[1, 0:5] y[10:15] = y_1[0, 5:10] y[15:20] = y_1[1, 5:10] y[20:25] = y_1[0, 10:15] y[25:30] = y_1[1, 10:15] y[30:35] = y_1[0, 15:20] y[35:40] = y_1[1, 15:20] return x, y
def random_sequence_rotation(seq, rotation_range, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0): """ apply a rotation to an entire sequence of frames args: seq : list (or array-like) - list of 3D input tensors rotation_range : int - amount to rotate in degrees row_axis : int - index of row axis on each tensor col_axis : int - index of cols axis on each tensor channel_axis : int - index of channel ax on each tensor fill_mode : string - points outside the boundaries of input are filled according to the given input mode, one of {'nearest', 'constant', 'reflect', 'wrap'} cval : float - constant value used for fill_mode constant returns: rotated : the rotated sequence of tensors """ theta = np.deg2rad(np.random.uniform(-rotation_range, rotation_range)) rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) h, w = seq[0].shape[row_axis], seq[0].shape[col_axis] transform_matrix = transform_matrix_offset_center(rotation_matrix, h, w) return [apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) for x in seq]
def augmentation3(x_0, x_1, x_2, x_3, y): theta = (np.random.uniform(-15, 15) * np.pi) / 180. rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) shear = np.random.uniform(-.1, .1) shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0], [0, 0, 1]]) zx, zy = np.random.uniform(.9, 1.1, 2) zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]]) augmentation_matrix = np.dot(np.dot(rotation_matrix, shear_matrix), zoom_matrix) transform_matrix = transform_matrix_offset_center(augmentation_matrix, x_0.shape[0], x_0.shape[1]) x_0 = apply_transform(x_0[..., np.newaxis], transform_matrix, channel_axis=2) x_1 = apply_transform(x_1[..., np.newaxis], transform_matrix, channel_axis=2) x_2 = apply_transform(x_2[..., np.newaxis], transform_matrix, channel_axis=2) x_3 = apply_transform(x_3[..., np.newaxis], transform_matrix, channel_axis=2) y = apply_transform(y[..., np.newaxis], transform_matrix, channel_axis=2) return x_0[..., 0], x_1[..., 0], x_2[..., 0], x_3[..., 0], y[..., 0]
def img_rotation(x, theta, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.): """modifed from keras random_rotation # Arguments x: Input tensor. Must be 3D. theta: Rotation range, in degrees. row_axis: Index of axis for rows in the input tensor. col_axis: Index of axis for columns in the input tensor. channel_axis: Index of axis for channels in the input tensor. fill_mode: Points outside the boundaries of the input are filled according to the given mode (one of `{'constant', 'nearest', 'reflect', 'wrap'}`). cval: Value used for points outside the boundaries of the input if `mode='constant'`. # Returns Rotated Numpy image tensor. """ # theta = np.pi / 180 * np.random.uniform(-rg, rg) rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) h, w = x.shape[row_axis], x.shape[col_axis] transform_matrix = transform_matrix_offset_center(rotation_matrix, h, w) x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) return x
def random_sequence_shear(seq, shear_range, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0): """ apply a random shear to an entire sequence of frames args: seq : list - the list of 3D input tensors shear_range : float - the amount of shear to apply row_axis : int - the index of row axis on each tensor col_axis : int - the index of col axis on each tensor channel_axis : int - the index of channel ax on each tensor fill_mode : string - points outside the boundaries of input are filled according to the given input mode, one of {'nearest', 'constant', 'reflect', 'wrap'} cval : float - the constant value used for fill_mode constant returns: the sequence of sheared frames """ shear = np.deg2rad(np.random.uniform(-shear_range, shear_range)) shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0], [0, 0, 1]]) h, w = seq[0].shape[row_axis], seq[0].shape[col_axis] transform_matrix = transform_matrix_offset_center(shear_matrix, h, w) return [apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) for x in seq]
def rotation(x, dg, row_axis=1, col_axis=2, channel_axis=0, fill_mode='bilinear', cval=0.): """Performs a random rotation of a Numpy image tensor. # Adguments x: Input tensor. Must be 3D. dg: Rotation degrees. row_axis: Index of axis for rows in the input tensor. col_axis: Index of axis for columns in the input tensor. channel_axis: Index of axis for channels in the input tensor. fill_mode: Points outside the boundaries of the input are filled according to the given mode (one of `{'constant', 'nearest', 'reflect', 'wrap'}`). cval: Value used for points outside the boundaries of the input if `mode='constant'`. # Returns Rotated Numpy image tensor. """ theta = np.pi/180 * dg rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) h, w = x.shape[row_axis], x.shape[col_axis] transform_matrix = transform_matrix_offset_center(rotation_matrix, h, w) x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) return x
def augmentation(x, y): theta = (np.random.uniform(-15, 15) * np.pi) / 180. rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) shear = np.random.uniform(-.1, .1) shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0], [0, 0, 1]]) zx, zy = np.random.uniform(.95, 1.05, 2) zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]]) augmentation_matrix = np.dot(np.dot(rotation_matrix, shear_matrix), zoom_matrix) transform_matrix = transform_matrix_offset_center(augmentation_matrix, x[0].shape[0], x[0].shape[1]) x_aug = np.zeros(x.shape, dtype=np.float32) for chan in range(x.shape[-1]): x_aug[:, :, chan:chan+1] = apply_transform(x[:, :, chan, np.newaxis], transform_matrix, channel_axis=2) # x_0 = apply_transform(x_0[..., np.newaxis], transform_matrix, channel_axis=2) # x_1 = apply_transform(x_1[..., np.newaxis], transform_matrix, channel_axis=2) y_aug = apply_transform(y, transform_matrix, channel_axis=2) return x_aug, y_aug
def a_zoom(img, zx, zy, fill_mode='nearest', cval=0.): x = img.copy() zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]]) h, w = x.shape[0], x.shape[1] transform_matrix = kimage.transform_matrix_offset_center( zoom_matrix, h, w) #保持中心坐标不改变 x = kimage.apply_transform(x, transform_matrix, 2, fill_mode, cval) return x
def zoom(x, zx, zy, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.): zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]]) h, w = x.shape[row_axis], x.shape[col_axis] transform_matrix = image.transform_matrix_offset_center(zoom_matrix, h, w) # 保持中心坐标不改变 x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) return x
def shear(x, shear, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.): shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0], [0, 0, 1]]) h, w = x.shape[row_axis], x.shape[col_axis] transform_matrix = image.transform_matrix_offset_center(shear_matrix, h, w) x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) return x
def rotate(x, theta, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.): rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) h, w = x.shape[row_axis], x.shape[col_axis] transform_matrix = image.transform_matrix_offset_center(rotation_matrix, h, w) x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) return x
def rotate(x, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.): rotate_limit=(-90, 90) theta = np.pi / 180 * np.random.uniform(rotate_limit[0], rotate_limit[1]) rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],[np.sin(theta), np.cos(theta), 0],[0, 0, 1]]) h, w = x.shape[row_axis], x.shape[col_axis] transform_matrix = image.transform_matrix_offset_center(rotation_matrix, h, w) x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) return x
def random_rotation(x, y, rg, row_index=1, col_index=2, channel_index=0, fill_mode='nearest', cval=0.): theta = np.pi / 180 * np.random.uniform(-rg, rg) rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) h, w = x.shape[row_index], x.shape[col_index] transform_matrix = transform_matrix_offset_center(rotation_matrix, h, w) x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval) y = apply_transform(y, transform_matrix, channel_index, fill_mode, cval) return x, y # # def random_shear(x, y, intensity, row_index=1, col_index=2, channel_index=0, # fill_mode='constant', cval=0.): # shear = np.random.uniform(-intensity, intensity) # shear_matrix = np.array([[1, -np.sin(shear), 0], # [0, np.cos(shear), 0], # [0, 0, 1]]) # # h, w = x.shape[row_index], x.shape[col_index] # transform_matrix = transform_matrix_offset_center(shear_matrix, h, w) # x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval) # y = apply_transform(y, transform_matrix, channel_index, fill_mode, cval) # return x, y # # def elastic_transform(image, mask, alpha, sigma, alpha_affine=None, random_state=None): # """Elastic deformation of images as described in [Simard2003]_ (with modifications). # .. [Simard2003] Simard, Steinkraus and Platt, "Best Practices for # Convolutional Neural Networks applied to Visual Document Analysis", in # Proc. of the International Conference on Document Analysis and # Recognition, 2003. # Based on https://gist.github.com/erniejunior/601cdf56d2b424757de5 # """ # if random_state is None: # random_state = np.random.RandomState(None) # # shape = image.shape # # dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma) * alpha # dy = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma) * alpha # # x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0])) # indices = np.reshape(y + dy, (-1, 1)), np.reshape(x + dx, (-1, 1)) # # res_x = map_coordinates(image, indices, order=1, mode='reflect').reshape(shape) # res_y = map_coordinates(mask, indices, order=1, mode='reflect').reshape(shape) # return res_x, res_y # def test(): # X = np.random.randint(0, 100, (1000, 1, 100, 200)) # YY = [np.random.randint(0, 100, (1000, 1, 100, 200)), np.random.random((1000, 1))] # cid = CustomImageDataGenerator(horizontal_flip=True, elastic=(100, 20)) # gen = cid.flow(X, YY, batch_size=64, shuffle=False) # n = gen.next()[0]
def _rotate_image(self, x3d, theta): theta = numpy.deg2rad(theta) rotation_matrix = numpy.array( [[numpy.cos(theta), -numpy.sin(theta), 0], [numpy.sin(theta), numpy.cos(theta), 0], [0, 0, 1]]) h, w, d = x3d.shape transform_matrix = transform_matrix_offset_center( rotation_matrix, h, w) xrot = apply_transform(x3d, transform_matrix, 2, 'nearest', 0) return xrot
def transform_img(self, transform_matrix, img): if transform_matrix is not None: h, w = img.shape[0], img.shape[1] transform_matrix = transform_matrix_offset_center( transform_matrix, h, w) img = apply_transform(img, transform_matrix, 2, fill_mode='nearest') return img
def zoom(x, zoom_range, row_index=1, col_index=2, channel_index=0, fill_mode='nearest', cval=0.): zx, zy = zoom_range zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]]) h, w = x.shape[row_index], x.shape[col_index] transform_matrix = transform_matrix_offset_center(zoom_matrix, h, w) x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval) return x
def a_rotate(img, theta, fill_mode='nearest', cval=0.): #theta为度数,正数是顺时针旋转 x = img.copy() theta = np.pi / 180 * theta #逆时针旋转角度 rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],\ [np.sin(theta), np.cos(theta), 0],[0, 0, 1]]) h, w = x.shape[0], x.shape[1] transform_matrix = kimage.transform_matrix_offset_center( rotation_matrix, h, w) x = kimage.apply_transform(x, transform_matrix, 2, fill_mode, cval) return x
def rotate(x, filepath, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.): x = np.array(x) rotate_limit = (-10, 10) theta = np.pi / 180 * np.random.uniform(rotate_limit[0], rotate_limit[1]) rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) h, w = x.shape[row_axis], x.shape[col_axis] transform_matrix = image.transform_matrix_offset_center(rotation_matrix, h, w) x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval) img = Image.fromarray(np.uint8(x)) img.save(filepath)
def rotate(img_rgb,img_range,counter,row_axis=0,col_axis=1,channel_axis=2,fill_mode='wrap',cval=0.): rotate_limit_1 = (-80,80) for i in range(5): theta_1 = np.pi / 180 * np.random.uniform(rotate_limit_1[0], rotate_limit_1[1]) rotation_matrix = np.array([[np.cos(theta_1), -np.sin(theta_1), 0], [np.sin(theta_1), np.cos(theta_1), 0], [0, 0, 1]]) h, w = img_rgb.shape[row_axis], img_rgb.shape[col_axis] transform_matrix = image.transform_matrix_offset_center(rotation_matrix, h, w) img_rgb_rotate = image.apply_transform(img_rgb, transform_matrix, channel_axis, fill_mode, cval) img_range_rotate = image.apply_transform(img_range, transform_matrix, channel_axis, fill_mode, cval) io.imsave('train_augmenta/'+str(counter)+'_rotate_'+str(i)+'.jpg',img_rgb_rotate) io.imsave('train_augmenta/'+str(counter)+'_rotate_'+str(i)+'.png',img_range_rotate)
def random_zoom(self, img, boxes): if self.zoom_prob < np.random.random(): return img, boxes original_img = np.copy(img) original_boxes = np.copy(boxes) r = np.random.uniform(self.zoom_range[0], self.zoom_range[1]) zoom_matrix = np.array([[r, 0, 0], [0, r, 0], [0, 0, 1]]) img_h = img.shape[0] img_w = img.shape[1] transform_matrix = transform_matrix_offset_center( zoom_matrix, img_h, img_w) #img = apply_affine_transform(img, zx=r, zy=r, channel_axis=2, fill_mode="constant", cval=1000) img = apply_transform(img, transform_matrix, 2, "constant", 1000) # 正解ボックスを変形させる w_rel = (boxes[:, [2]] - boxes[:, [0]]) / r h_rel = (boxes[:, [3]] - boxes[:, [1]]) / r dx = (boxes[:, [0]] - 0.5) * (1 - 1 / r) dy = (boxes[:, [1]] - 0.5) * (1 - 1 / r) boxes[:, [0]] -= dx boxes[:, [1]] -= dy boxes[:, [2]] = boxes[:, [0]] + w_rel boxes[:, [3]] = boxes[:, [1]] + h_rel for box in boxes: cx = 0.5 * (box[0] + box[2]) cy = 0.5 * (box[1] + box[3]) w = box[2] - box[0] h = box[3] - box[1] if (cx < 0.0 or 1.0 < cx or cy < 0.0 or 1.0 < cy) or (w < 0.2 or h < 0.2): # 正解ボックスの中心が拡大後に無くなる場合や極端に小さくなる場合は変換前の画像を返す return original_img, original_boxes boxes = np.clip(boxes, 0.0, 1.0) #for box in boxes: # coord = (box[0]*img_w, box[1]*img_h), (box[2]-box[0])*img_w, (box[3]-box[1])*img_h # colors = plt.cm.hsv(np.linspace(0, 1, 21)).tolist() # plt.imshow(img / 255.) # currentAxis = plt.gca() # currentAxis.add_patch(plt.Rectangle(*coord, fill=False, edgecolor=colors[3], linewidth=8)) # plt.savefig("zoom_sample.jpg") # plt.clf() return img, boxes
def apply_transform_matrix(self, img: np.ndarray, transform_matrix): """ Apply transformation matrix to image img :param self: self :param img: image :param transform_matrix: transformation matrix :return: transformed image """ h, w = img.shape[0], img.shape[1] transform_matrix = transform_matrix_offset_center(transform_matrix, h, w) img = apply_transform(img, transform_matrix, channel_axis=2, fill_mode=self.fill_mode, cval=self.cval) return img
def __zoom__(x, zx, zy): """ Zoom into the image. Args: x: Array. The input image. zx: Float. The amount of zoom on the horizontal axis. zy: Float. The amount of zoom on the vertical axis. Returns: The zoomed image. """ zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]]) transform_matrix = image.transform_matrix_offset_center( zoom_matrix, x.shape[0], x.shape[1]) return image.apply_transform(x, transform_matrix, 2, 'nearest', 0.0)
def __rotate__(x, theta): """ Rotates the image. Args: x: Array. The input image. theta: Float. The rotation angle. Returns: The rotated image. """ rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) transform_matrix = image.transform_matrix_offset_center( rotation_matrix, x.shape[0], x.shape[1]) return image.apply_transform(x, transform_matrix, 2, 'nearest', 0.0)
def __shear__(x, shear, rotate_dir): """ Shear the image. Args: x: Array. The input image. shear: Float. The amount of shear. rotate_dir: Integer. The direction of rotation. Takes value of either -1 or 1. Returns: The sheared image. """ shear_matrix = np.array([[1, rotate_dir * np.sin(shear), 0], [0, np.cos(shear), 0], [0, 0, 1]]) transform_matrix = image.transform_matrix_offset_center( shear_matrix, x.shape[0], x.shape[1]) return image.apply_transform(x, transform_matrix, 2, 'nearest', 0.0)
def random_shear(x, y, intensity, row_index=1, col_index=2, channel_index=0, fill_mode='constant', cval=0.): shear = np.random.uniform(-intensity, intensity) shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0], [0, 0, 1]]) h, w = x.shape[row_index], x.shape[col_index] transform_matrix = transform_matrix_offset_center(shear_matrix, h, w) x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval) y = apply_transform(y, transform_matrix, channel_index, fill_mode, cval) return x, y
def build_transform(self, shape): img_row_index = self.row_index - 1 img_col_index = self.col_index - 1 img_channel_index = self.channel_index - 1 # use composition of homographies to generate final transform that needs to be applied if self.rotation_range: theta = np.pi / 180 * np.random.uniform(-self.rotation_range, self.rotation_range) else: theta = 0 rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) if self.height_shift_range: tx = np.random.uniform( -self.height_shift_range, self.height_shift_range) * shape[img_row_index] else: tx = 0 if self.width_shift_range: ty = np.random.uniform( -self.width_shift_range, self.width_shift_range) * shape[img_col_index] else: ty = 0 translation_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]]) if self.shear_range: shear = np.random.uniform(-self.shear_range, self.shear_range) else: shear = 0 shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0], [0, 0, 1]]) if self.zoom_range[0] == 1 and self.zoom_range[1] == 1: zx, zy = 1, 1 else: zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1], 2) zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]]) transform_matrix = np.dot( np.dot(np.dot(rotation_matrix, translation_matrix), shear_matrix), zoom_matrix) h, w = shape[img_row_index], shape[img_col_index] transform_matrix = transform_matrix_offset_center( transform_matrix, h, w) return img_channel_index, img_col_index, img_row_index, transform_matrix
def random_rotation(x, y, rg, row_index=0, col_index=1, channel_index=2, fill_mode='nearest', cval=0.): theta = np.pi / 180 * np.random.uniform(-rg, rg) rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) h, w = x.shape[row_index], x.shape[col_index] transform_matrix = transform_matrix_offset_center(rotation_matrix, h, w) x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval) y = apply_transform(y, transform_matrix, channel_index, fill_mode, cval) return x, y
def random_transform_with_states(self, x, seed=None): """Randomly augment a single image tensor. # Arguments x: 3D tensor, single image. seed: random seed. # Returns A tuple. 0 -> randomly transformed version of the input (same shape). 1 -> true if image was horizontally flipped, false otherwise """ # x is a single image, so it doesn't have image number at index 0 img_row_axis = self.row_axis img_col_axis = self.col_axis img_channel_axis = self.channel_axis is_image_horizontally_flipped = False # use composition of homographies # to generate final transform that needs to be applied if self.rotation_range: theta = np.pi / 180 * np.random.uniform(-self.rotation_range, self.rotation_range) else: theta = 0 if self.height_shift_range: tx = np.random.uniform(-self.height_shift_range, self.height_shift_range) * x.shape[img_row_axis] else: tx = 0 if self.width_shift_range: ty = np.random.uniform(-self.width_shift_range, self.width_shift_range) * x.shape[img_col_axis] else: ty = 0 if self.shear_range: shear = np.random.uniform(-self.shear_range, self.shear_range) else: shear = 0 if self.zoom_range[0] == 1 and self.zoom_range[1] == 1: zx, zy = 1, 1 else: zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1], 2) transform_matrix = None if theta != 0: rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) transform_matrix = rotation_matrix if tx != 0 or ty != 0: shift_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]]) transform_matrix = shift_matrix if transform_matrix is None else np.dot(transform_matrix, shift_matrix) if shear != 0: shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0], [0, 0, 1]]) transform_matrix = shear_matrix if transform_matrix is None else np.dot(transform_matrix, shear_matrix) if zx != 1 or zy != 1: zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]]) transform_matrix = zoom_matrix if transform_matrix is None else np.dot(transform_matrix, zoom_matrix) if transform_matrix is not None: h, w = x.shape[img_row_axis], x.shape[img_col_axis] transform_matrix = image.transform_matrix_offset_center(transform_matrix, h, w) x = image.apply_transform(x, transform_matrix, img_channel_axis, fill_mode=self.fill_mode, cval=self.cval) if self.channel_shift_range != 0: x = image.random_channel_shift(x, self.channel_shift_range, img_channel_axis) if self.horizontal_flip: if np.random.random() < 0.5: x = image.flip_axis(x, img_col_axis) is_image_horizontally_flipped = True if self.vertical_flip: if np.random.random() < 0.5: x = image.flip_axis(x, img_row_axis) if self.brighten_range != 0: random_bright = np.random.uniform(low = 1.0-self.brighten_range, high=1.0+self.brighten_range) #TODO: Write this as an apply to push operations into C for performance img = cv2.cvtColor(x, cv2.COLOR_RGB2HSV) img[:, :, 2] = np.clip(img[:, :, 2] * random_bright, 0, 255) x = cv2.cvtColor(img, cv2.COLOR_HSV2RGB) return (x, is_image_horizontally_flipped)