def test_random_transforms(self): x = np.random.random((2, 28, 28)) assert image.random_rotation(x, 45).shape == (2, 28, 28) assert image.random_shift(x, 1, 1).shape == (2, 28, 28) assert image.random_shear(x, 20).shape == (2, 28, 28) assert image.random_zoom(x, (5, 5)).shape == (2, 28, 28) assert image.random_channel_shift(x, 20).shape == (2, 28, 28)
def do_tta(x, tta_types): if 'hflip' in tta_types: x = flip_axis(x, 1) if 'vflip' in tta_types: x = flip_axis(x, 0) if 'channel_shift' in tta_types: x = random_channel_shift(x, 0.2, 2) return x
def test_img_transforms(self): x = np.random.random((3, 200, 200)) _ = preprocessing_image.random_rotation(x, 20) _ = preprocessing_image.random_shift(x, 0.2, 0.2) _ = preprocessing_image.random_shear(x, 2.) _ = preprocessing_image.random_zoom(x, (0.5, 0.5)) _ = preprocessing_image.apply_channel_shift(x, 2, 2) _ = preprocessing_image.apply_affine_transform(x, 2) with self.assertRaises(ValueError): preprocessing_image.random_zoom(x, (0, 0, 0)) _ = preprocessing_image.random_channel_shift(x, 2.)
def test_random_transforms(self): x = np.random.random((2, 28, 28)) assert image.random_rotation(x, 45).shape == (2, 28, 28) assert image.random_shift(x, 1, 1).shape == (2, 28, 28) assert image.random_shear(x, 20).shape == (2, 28, 28) assert image.random_zoom(x, (5, 5)).shape == (2, 28, 28) assert image.random_channel_shift(x, 20).shape == (2, 28, 28) # Test get_random_transform with predefined seed seed = 1 generator = image.ImageDataGenerator( rotation_range=90., width_shift_range=0.1, height_shift_range=0.1, shear_range=0.5, zoom_range=0.2, channel_shift_range=0.1, brightness_range=(1, 5), horizontal_flip=True, vertical_flip=True) transform_dict = generator.get_random_transform(x.shape, seed) transform_dict2 = generator.get_random_transform(x.shape, seed * 2) assert transform_dict['theta'] != 0 assert transform_dict['theta'] != transform_dict2['theta'] assert transform_dict['tx'] != 0 assert transform_dict['tx'] != transform_dict2['tx'] assert transform_dict['ty'] != 0 assert transform_dict['ty'] != transform_dict2['ty'] assert transform_dict['shear'] != 0 assert transform_dict['shear'] != transform_dict2['shear'] assert transform_dict['zx'] != 0 assert transform_dict['zx'] != transform_dict2['zx'] assert transform_dict['zy'] != 0 assert transform_dict['zy'] != transform_dict2['zy'] assert transform_dict['channel_shift_intensity'] != 0 assert (transform_dict['channel_shift_intensity'] != transform_dict2['channel_shift_intensity']) assert transform_dict['brightness'] != 0 assert transform_dict['brightness'] != transform_dict2['brightness'] # Test get_random_transform without any randomness generator = image.ImageDataGenerator() transform_dict = generator.get_random_transform(x.shape, seed) assert transform_dict['theta'] == 0 assert transform_dict['tx'] == 0 assert transform_dict['ty'] == 0 assert transform_dict['shear'] == 0 assert transform_dict['zx'] == 1 assert transform_dict['zy'] == 1 assert transform_dict['channel_shift_intensity'] is None assert transform_dict['brightness'] is None
def augmentation(self, X, Y): print('Augmentation model...') total = len(X) x_train, y_train = [], [] for i in range(total): if i % 100 == 0: print('Aug', i) x, y = X[i], Y[i] #standart x_train.append(x) y_train.append(y) for _ in range(2): _x, _y = elastic_transform(x[0], y[0], 100, 20) x_train.append(_x.reshape((1, ) + _x.shape)) y_train.append(_y.reshape((1, ) + _y.shape)) #flip x x_train.append(flip_axis(x, 2)) y_train.append(flip_axis(y, 2)) #flip y x_train.append(flip_axis(x, 1)) y_train.append(flip_axis(y, 1)) continue #zoom for _ in range(1): _x, _y = random_zoom(x, y, (0.9, 1.1)) x_train.append(_x) y_train.append(_y) #intentsity for _ in range(1): _x = random_channel_shift(x, 5.0) x_train.append(_x) y_train.append(y) # for j in range(5): # xs, ys = load_aug(j) # ys = self.norm_mask(ys) # (xn, yn), _ = self.split_train_and_valid_by_patient(xs, ys, validation_split=self.validation_split, shuffle=False) # for i in range(len(xn)): # x_train.append(xn[i]) # y_train.append(yn[i]) x_train = np.array(x_train) y_train = np.array(y_train) return x_train, y_train
def augmentation(self, X, Y): print('Augmentation model...') total = len(X) x_train, y_train = [], [] for i in xrange(total): x, y = X[i], Y[i] #standart x_train.append(x) y_train.append(y) # for _ in xrange(1): # _x, _y = elastic_transform(x[0], y[0], 100, 20) # x_train.append(_x.reshape((1,) + _x.shape)) # y_train.append(_y.reshape((1,) + _y.shape)) #flip x x_train.append(flip_axis(x, 2)) y_train.append(flip_axis(y, 2)) #flip y x_train.append(flip_axis(x, 1)) y_train.append(flip_axis(y, 1)) #continue #zoom for _ in xrange(1): _x, _y = random_zoom(x, y, (0.9, 1.1)) x_train.append(_x) y_train.append(_y) for _ in xrange(0): _x, _y = random_rotation(x, y, 5) x_train.append(_x) y_train.append(_y) #intentsity for _ in xrange(1): _x = random_channel_shift(x, 5.0) x_train.append(_x) y_train.append(y) x_train = np.array(x_train) y_train = np.array(y_train) print('x_trian: ', x_train.shape) return x_train, y_train
def random_transform(self, *args): """ Override original `random_transform` Randomly augment list of single image tensors. # Arguments *args: list of 3D ndarrays of same shape # Returns A randomly transformed inputs (same shape). """ assert len(args) > 0, "List of arguments should not be empty" output_args = list(args) img_channel_axis = self.channel_axis - 1 img_row_axis = self.row_axis - 1 img_col_axis = self.col_axis - 1 transform_matrix = self._get_random_transform_matrix( output_args[0].shape) if transform_matrix is not None: for i, arg in enumerate(output_args): output_args[i] = apply_transform(arg, transform_matrix, img_channel_axis, fill_mode=self.fill_mode, cval=self.cval) if self.channel_shift_range != 0: for i, arg in enumerate(output_args): output_args[i] = random_channel_shift(arg, self.channel_shift_range, img_channel_axis) if self.horizontal_flip: if np.random.random() < 0.5: for i, arg in enumerate(output_args): output_args[i] = flip_axis(arg, img_col_axis) if self.vertical_flip: if np.random.random() < 0.5: for i, arg in enumerate(output_args): output_args[i] = flip_axis(arg, img_row_axis) return output_args[0] if len(output_args) == 1 else output_args
def random_transform(self, x, y): x_shape = None for x_sub in x: if x_sub[1]: x_shape = x_sub.shape img_channel_index, img_col_index, img_row_index, transform_matrix = self.build_transform( x_shape) flip_horiz_choice, flip_vert_choice = np.random.random(2) < 0.5 for x_i in range(len(x)): if x[x_i][1]: to_transform = x[x_i][0] to_transform = self.spatial_transforms( flip_horiz_choice, flip_vert_choice, img_channel_index, img_col_index, img_row_index, to_transform, transform_matrix) if self.channel_shift_range != 0: to_transform = random_channel_shift( to_transform, self.channel_shift_range, img_channel_index) x[x_i][0] = to_transform if y is not None: for y_i in range(len(y)): if y[y_i][1]: to_transform = y[y_i][0] to_transform = self.spatial_transforms( flip_horiz_choice, flip_vert_choice, img_channel_index, img_col_index, img_row_index, to_transform, transform_matrix) y[y_i][0] = to_transform # TODO: # channel-wise normalization # barrel/fisheye return x, y
def random_transform(self, x, y=None, seed=None): """Randomly augment a single image tensor. # Arguments x: 3D tensor, single image. seed: random seed. # Returns A randomly transformed version of the input (same shape). """ # x is a single image, so it doesn't have image number at index 0 img_row_axis = self.row_axis - 1 img_col_axis = self.col_axis - 1 img_channel_axis = self.channel_axis - 1 if seed is not None: np.random.seed(seed) # 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 = transform_matrix_offset_center(transform_matrix, h, w) x = apply_transform(x, transform_matrix, img_channel_axis, fill_mode=self.fill_mode, cval=self.cval) if y is not None: y = apply_transform(y, transform_matrix, img_channel_axis, fill_mode=self.fill_mode, cval=self.cval) if self.channel_shift_range != 0: x = random_channel_shift(x, self.channel_shift_range, img_channel_axis) if (self.hue_range != 0) | (self.saturation_power_range[0] != 1) | (self.value_power_range[0] != 1): x = cv2.cvtColor(x, cv2.COLOR_RGB2HSV) h, s, v = cv2.split(x) #pdb.set_trace() if self.hue_range != 0: hue_shift = np.random.uniform(-self.hue_range, self.hue_range) h = cv2.add(h, hue_shift) if self.saturation_power_range[0] != 1: if np.random.random() < 0.5: sat_shift = np.random.uniform(self.saturation_power_range[0], 1) else: sat_shift = np.random.uniform(1, self.saturation_power_range[1]) #print("Saturation Power: {}".format(sat_shift)) s = cv2.pow(s, sat_shift) if self.value_power_range[0] != 1: if np.random.random() < 0.5: val_shift = np.random.uniform(self.value_power_range[0], 1) else: val_shift = np.random.uniform(1, self.value_power_range[1]) #print("Value Power: {}".format(val_shift)) v = cv2.pow(v/255., val_shift)*255. x = cv2.merge((h, s, v)) x = cv2.cvtColor(x, cv2.COLOR_HSV2RGB) if self.horizontal_flip: if np.random.random() < 0.5: x = flip_axis(x, img_col_axis) if y is not None: y = flip_axis(y, img_col_axis) if self.vertical_flip: if np.random.random() < 0.5: x = flip_axis(x, img_row_axis) if y is not None: y = flip_axis(y, img_row_axis) if y is not None: return x, y return x
def _load_batch_helper(inputDict, augmentation): """ Helper for load_cnn_batch that actually loads imagery and supports parallel processing :param inputDict: dict containing the data and metadataStats that will be used to load imagery :return currOutput: dict with image data, metadata, and the associated label """ datas = inputDict['data'] metadataStats = inputDict['metadataStats'] num_labels = inputDict['num_labels'] # for 0-views make it a list so we can iterate later if not isinstance(datas, (list, tuple)): datas = [datas] currOutputs = [ ] target_img_size = inputDict['target_img_size'] if augmentation: random_offset = (np.random.random((2,)) - 0.5 ) * (inputDict['offset'] * target_img_size) random_angle = (np.random.random() - 0.5 ) * inputDict['angle'] random_zoom = np.random.uniform(1. - inputDict['zoom'] / 2., 1 + inputDict['zoom'] / 2.) flip_v = (np.random.random() < 0.5) and inputDict['flip_east_west'] flip_h = (np.random.random() < 0.5) and inputDict['flip_north_south'] else: random_offset = np.zeros(2,) random_zoom = 1. random_angle = 0. flip_v = flip_h = False if inputDict['views'] != 0: datas = random.sample(datas, inputDict['views']) timestamps = [] for data in datas: metadata = json.load(open(data['features_path'])) timestamps.append(get_timestamp(metadata)) img = scipy.misc.imread(data['img_path']) if inputDict['jitter_channel'] != 0 and augmentation: img = random_channel_shift(img, inputDict['jitter_channel'] * 255., 2) if (random_angle != 0. or random_zoom != 1.) and augmentation: patch_size = img.shape[0] patch_center = patch_size / 2 sq2 = 1.4142135624 src_points = np.float32([ [ patch_center - target_img_size / 2 , patch_center - target_img_size / 2 ], [ patch_center + target_img_size / 2 , patch_center - target_img_size / 2 ], [ patch_center + target_img_size / 2 , patch_center + target_img_size / 2 ]]) # src_points are rotated COUNTER-CLOCKWISE src_points = rotate(src_points, random_angle, img.shape) src_points = zoom(src_points, random_zoom, img.shape) src_points += random_offset # dst_points are fixed dst_points = np.float32([ [ 0 , 0 ], [ target_img_size - 1, 0 ], [ target_img_size - 1, target_img_size - 1]]) # this is effectively a CLOCKWISE rotation M = cv2.getAffineTransform(src_points.astype(np.float32), dst_points) img = cv2.warpAffine(img, M, (target_img_size, target_img_size), borderMode = cv2.BORDER_REFLECT_101).astype(np.float32) else: crop_size = target_img_size x0 = int(img.shape[1]/2 - crop_size/2 + random_offset[0]) x1 = x0 + crop_size y0 = int(img.shape[0]/2 - crop_size/2 + random_offset[1]) y1 = y0 + crop_size img = img[y0:y1, x0:x1,...].astype(np.float32) if flip_h: img = flip_axis(img, 1) # flips > into < if flip_v: img = flip_axis(img, 0) # flips ^ into v #show_image(img.astype(np.uint8)) #raw_input("Press enter") if augmentation: metadata = transform_metadata(metadata, flip_h=flip_h, flip_v=flip_v, angle=random_angle, zoom=random_zoom) if inputDict['jitter_metadata'] != 0: metadata = jitter_metadata(metadata, inputDict['jitter_metadata'], metadataStats['metadata_max']) img = imagenet_utils.preprocess_input(img) / 255. labels = to_categorical(data['category'], num_labels) currOutput = {} currOutput['img'] = copy.deepcopy(img) metadata = np.divide(json.load(open(data['features_path'])) - np.array(metadataStats['metadata_mean']), metadataStats['metadata_max']) if inputDict['mask_metadata']: metadata = mask_metadata(metadata) currOutput['metadata'] = metadata currOutput['labels'] = labels currOutputs.append(currOutput) if (len(currOutputs) == 1) and (inputDict['views'] == 0): currOutputs = currOutputs[0] else: # sort by timestamp sortedInds = sorted(range(len(timestamps)), key=lambda k:timestamps[k]) currOutputs = [currOutputs[i] for i in sortedInds] return currOutputs
def random_transform(self, x, seed=None): """Randomly augments a single image tensor. Rotation and image flips are applied to both satellite and roadmap. Channel shifts and brightness changes are applied to satellite only. # Arguments x: 3D tensor, single image. seed: Random seed. # Returns A randomly transformed version of the input (same shape). """ # x is a single image, so it doesn't have image number at index 0 img_row_axis = self.row_axis - 1 img_col_axis = self.col_axis - 1 img_channel_axis = self.channel_axis - 1 if seed is not None: np.random.seed(seed) # Use composition of homographies # to generate final transform that needs to be applied if self.rotation_range: theta = np.deg2rad( np.random.uniform(-self.rotation_range, self.rotation_range)) else: theta = 0 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 transform_matrix is not None: h, w = x.shape[img_row_axis], x.shape[img_col_axis] transform_matrix = transform_matrix_offset_center( transform_matrix, h, w) x = apply_transform(x, transform_matrix, img_channel_axis, fill_mode=self.fill_mode, cval=self.cval) if self.horizontal_flip: if np.random.random() < 0.5: x = flip_axis(x, img_col_axis) if self.vertical_flip: if np.random.random() < 0.5: x = flip_axis(x, img_row_axis) x = np.moveaxis(x, img_channel_axis, -1) x_satellite = x[:, :, 0:3] x_roadmap = x[:, :, 3:6] if self.channel_shift_range != 0: x_satellite = random_channel_shift(x_satellite, self.channel_shift_range, img_channel_axis) if self.brightness_range is not None: x_satellite = random_brightness(x_satellite, self.brightness_range) x = np.concatenate([x_satellite, x_roadmap], axis=-1) x = np.moveaxis(x, -1, img_channel_axis) return x
def random_transform(self, x, mask): """Randomly augment a image tensor and mask. # Arguments x: 3D tensor, single image. # Returns A randomly transformed version of the input (same shape). """ # x is a single image, so it doesn't have image number at index 0 img_row_axis = 0 img_col_axis = 1 img_channel_axis = 2 # use composition of homographies # to generate final transform that needs to be applied if self.rotation_range and np.random.random() < 0.3: theta = np.pi / 180 * np.random.uniform(-self.rotation_range, self.rotation_range) else: theta = 0 if self.height_shift_range: uniform = np.random.uniform(-self.height_shift_range, self.height_shift_range) tx = uniform * x.shape[img_row_axis] tmx = uniform * mask.shape[img_row_axis] else: tx = 0 tmx = 0 if self.width_shift_range: random_uniform = np.random.uniform(-self.width_shift_range, self.width_shift_range) ty = random_uniform * x.shape[img_col_axis] tmy = random_uniform * mask.shape[img_col_axis] else: ty = 0 tmy = 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 transform_matrix_mask = 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 transform_matrix_mask = rotation_matrix if tx != 0 or ty != 0: shift_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]]) shift_matrix_mask = np.array([[1, 0, tmx], [0, 1, tmy], [0, 0, 1]]) transform_matrix = shift_matrix if transform_matrix is None else np.dot(transform_matrix, shift_matrix) transform_matrix_mask = shift_matrix_mask if transform_matrix_mask is None else np.dot(transform_matrix_mask, shift_matrix_mask) 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) transform_matrix_mask = shear_matrix if transform_matrix_mask is None else np.dot(transform_matrix_mask, 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) transform_matrix_mask = zoom_matrix if transform_matrix_mask is None else np.dot(transform_matrix_mask, zoom_matrix) if transform_matrix is not None: h, w = x.shape[img_row_axis], x.shape[img_col_axis] transform_matrix = transform_matrix_offset_center(transform_matrix, h, w) x = apply_transform(x, transform_matrix, img_channel_axis, fill_mode=self.fill_mode, cval=self.cval) if transform_matrix_mask is not None: h, w = mask.shape[img_row_axis], mask.shape[img_col_axis] transform_matrix_mask = transform_matrix_offset_center(transform_matrix_mask, h, w) mask[:, :, :] = apply_transform(mask[:, :, :], transform_matrix_mask, img_channel_axis, fill_mode='constant', cval=0.) if self.channel_shift_range != 0: x = random_channel_shift(x, self.channel_shift_range, img_channel_axis) if self.horizontal_flip: if np.random.random() < 0.5: x = flip_axis(x, img_col_axis) mask = flip_axis(mask, img_col_axis) if self.vertical_flip: if np.random.random() < 0.5: x = flip_axis(x, img_row_axis) mask = flip_axis(mask, img_row_axis) return x, mask
def random_transform(self, x, y=None): # x is a single image, so it doesn't have image number at index 0 img_row_index = self.row_index - 1 img_col_index = self.col_index - 1 img_channel_index = self.channel_index - 1 # prepare the data if GT is detection if self.class_mode == 'detection': h, w = x.shape[img_row_index], x.shape[img_col_index] # convert relative coordinates x,y,w,h to absolute x1,y1,x2,y2 b = np.copy(y[:,1:5]) b[:,0] = y[:,1]*w - y[:,3]*w/2 b[:,1] = y[:,2]*h - y[:,4]*h/2 b[:,2] = y[:,1]*w + y[:,3]*w/2 b[:,3] = y[:,2]*h + y[:,4]*h/2 # use composition of homographies to generate final transform that # needs to be applied need_transform = False # Rotation if self.rotation_range: theta = np.pi / 180 * np.random.uniform(-self.rotation_range, self.rotation_range) need_transform = True else: theta = 0 # Shift in height if self.height_shift_range: tx = np.random.uniform(-self.height_shift_range, self.height_shift_range) * x.shape[img_row_index] need_transform = True else: tx = 0 # Shift in width if self.width_shift_range: ty = np.random.uniform(-self.width_shift_range, self.width_shift_range) * x.shape[img_col_index] need_transform = True else: ty = 0 # Shear if self.shear_range: shear = np.random.uniform(-self.shear_range, self.shear_range) need_transform = True else: shear = 0 # Zoom 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) need_transform = True if need_transform: rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) translation_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]]) shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0], [0, 0, 1]]) 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 = x.shape[img_row_index], x.shape[img_col_index] transform_matrix = transform_matrix_offset_center(transform_matrix, h, w) x = apply_transform(x, transform_matrix, img_channel_index, fill_mode=self.fill_mode, cval=self.cval) if y is not None: if self.has_gt_image: y = apply_transform(y, transform_matrix, img_channel_index, fill_mode=self.fill_mode, cval=self.void_label) elif self.class_mode == 'detection': # point transformation is the inverse of image transformation p_transform_matrix = inv(transform_matrix) for ii in range(b.shape[0]): x1,y1,x2,y2 = b.astype(int)[ii] # get the four edge points of the bounding box v1 = np.array([y1,x1,1]) v2 = np.array([y2,x2,1]) v3 = np.array([y2,x1,1]) v4 = np.array([y1,x2,1]) # transform the 4 points v1 = np.dot(p_transform_matrix, v1) v2 = np.dot(p_transform_matrix, v2) v3 = np.dot(p_transform_matrix, v3) v4 = np.dot(p_transform_matrix, v4) # compute the new bounding box edges b[ii,0] = np.min([v1[1],v2[1],v3[1],v4[1]]) b[ii,1] = np.min([v1[0],v2[0],v3[0],v4[0]]) b[ii,2] = np.max([v1[1],v2[1],v3[1],v4[1]]) b[ii,3] = np.max([v1[0],v2[0],v3[0],v4[0]]) if self.channel_shift_range != 0: x = random_channel_shift(x, self.channel_shift_range, img_channel_index) if (self.saturation_scale_range > 1) or (self.exposure_scale_range > 1) or (self.hue_shift_range != 0): if img_channel_index == 2: hsv = cv2.cvtColor(x, cv2.COLOR_RGB2HSV) elif img_channel_index == 0: hsv = cv2.cvtColor(np.transpose(x,(1,2,0)), cv2.COLOR_RGB2HSV) if self.hue_shift_range != 0: shift = 360*np.random.uniform(-self.hue_shift_range,self.hue_shift_range) hsv[:,:,0] = np.clip(hsv[:,:,0]+shift, 0, 360) if self.saturation_scale_range > 1: scale = np.random.uniform(1,self.saturation_scale_range) if np.random.uniform() > 0.5: scale = 1./scale hsv[:,:,1] = np.clip(hsv[:,:,1]*scale, 0, 1) if self.exposure_scale_range > 1: scale = np.random.uniform(1,self.saturation_scale_range) if np.random.uniform() > 0.5: scale = 1./scale hsv[:,:,2] = np.clip(hsv[:,:,2]*scale, 0, 1) x = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB) if img_channel_index == 0: x = np.transpose(x,(2,0,1)) if self.horizontal_flip: if np.random.random() < 0.5: x = flip_axis(x, img_col_index) if y is not None: if self.has_gt_image: y = flip_axis(y, img_col_index) elif self.class_mode == 'detection': b[:,0],b[:,2] = w - b[:,2], w - b[:,0] if self.vertical_flip: if np.random.random() < 0.5: x = flip_axis(x, img_row_index) if y is not None: if self.has_gt_image: y = flip_axis(y, img_row_index) elif self.class_mode == 'detection': b[:,1],b[:,3] = h - b[:,3], h - b[:,1] if self.spline_warp: warp_field = gen_warp_field(shape=x.shape[-2:], sigma=self.warp_sigma, grid_size=self.warp_grid_size) x = apply_warp(x, warp_field, interpolator=sitk.sitkLinear, fill_mode=self.fill_mode, fill_constant=self.cval) if y is not None: if self.has_gt_image: y = np.round(apply_warp(y, warp_field, interpolator=sitk.sitkNearestNeighbor, fill_mode=self.fill_mode, fill_constant=self.void_label)) elif self.class_mode == 'detection': raise ValueError('Elastic deformation is not supported for class_mode:', self.class_mode) # Crop # TODO: tf compatible??? crop = list(self.crop_size) if self.crop_size else None if crop: # print ('X before: ' + str(x.shape)) # print ('Y before: ' + str(y.shape)) # print ('Crop_size: ' + str(self.crop_size)) h, w = x.shape[img_row_index], x.shape[img_col_index] # Padd image if it is smaller than the crop size pad_h1, pad_h2, pad_w1, pad_w2 = 0, 0, 0, 0 if h < crop[0]: total_pad = crop[0] - h pad_h1 = total_pad/2 pad_h2 = total_pad-pad_h1 if w < crop[1]: total_pad = crop[1] - w pad_w1 = total_pad/2 pad_w2 = total_pad - pad_w1 if h < crop[0] or w < crop[1]: x = np.lib.pad(x, ((0, 0), (pad_h1, pad_h2), (pad_w1, pad_w2)), 'constant') if y is not None: if self.has_gt_image: y = np.lib.pad(y, ((0, 0), (pad_h1, pad_h2), (pad_w1, pad_w2)), 'constant', constant_values=self.void_label) elif self.class_mode == 'detection': b[:,0] = b[:,0] + pad_w1 b[:,1] = b[:,1] + pad_h1 b[:,2] = b[:,2] + pad_w1 b[:,3] = b[:,3] + pad_h1 h, w = x.shape[img_row_index], x.shape[img_col_index] # print ('New size X: ' + str(x.shape)) # print ('New size Y: ' + str(y.shape)) # exit() if crop[0] < h: top = np.random.randint(h - crop[0]) else: #print('Data augmentation: Crop height >= image size') top, crop[0] = 0, h if crop[1] < w: left = np.random.randint(w - crop[1]) else: #print('Data augmentation: Crop width >= image size') left, crop[1] = 0, w if self.dim_ordering == 'th': x = x[..., :, top:top+crop[0], left:left+crop[1]] if y is not None: if self.has_gt_image: y = y[..., :, top:top+crop[0], left:left+crop[1]] else: x = x[..., top:top+crop[0], left:left+crop[1], :] if y is not None: if self.has_gt_image: y = y[..., top:top+crop[0], left:left+crop[1], :] if self.class_mode == 'detection': b[:,0] = b[:,0] - left b[:,1] = b[:,1] - top b[:,2] = b[:,2] - left b[:,3] = b[:,3] - top # print ('X after: ' + str(x.shape)) # print ('Y after: ' + str(y.shape)) if self.class_mode == 'detection': # clamp to valid coordinate values b[:,0] = np.clip( b[:,0] , 0 , w ) b[:,1] = np.clip( b[:,1] , 0 , h ) b[:,2] = np.clip( b[:,2] , 0 , w ) b[:,3] = np.clip( b[:,3] , 0 , h ) # convert back from absolute x1,y1,x2,y2 coordinates to relative x,y,w,h y[:,1] = (b[:,0] + (b[:,2]-b[:,0])/2 ) / w y[:,2] = (b[:,1] + (b[:,3]-b[:,1])/2 ) / h y[:,3] = (b[:,2]-b[:,0]) / w y[:,4] = (b[:,3]-b[:,1]) / h # reject regions that are too small y = y[y[:,3]>0.005] y = y[y[:,4]>0.005] if y.shape[0] == 0: warnings.warn('DirectoryIterator: your data augmentation strategy ' 'is is moving all the boxes out of the image ') # TODO: # channel-wise normalization # barrel/fisheye # blur 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)
def random_transform(self, x, y=None): # x is a single image, so it doesn't have image number at index 0 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) * x.shape[img_row_index] else: tx = 0 if self.width_shift_range: ty = np.random.uniform( -self.width_shift_range, self.width_shift_range) * x.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 = x.shape[img_row_index], x.shape[img_col_index] transform_matrix = transform_matrix_offset_center( transform_matrix, h, w) x = apply_transform(x, transform_matrix, img_channel_index, fill_mode=self.fill_mode, cval=self.cval) if y is not None: y = apply_transform(y, transform_matrix, img_channel_index, fill_mode=self.fill_mode, cval=self.void_label) if self.channel_shift_range != 0: x = random_channel_shift(x, self.channel_shift_range, img_channel_index) if self.horizontal_flip: if np.random.random() < 0.5: x = flip_axis(x, img_col_index) if y is not None: y = flip_axis(y, img_col_index) if self.vertical_flip: if np.random.random() < 0.5: x = flip_axis(x, img_row_index) if y is not None: y = flip_axis(y, img_row_index) if self.spline_warp: warp_field = gen_warp_field(shape=x.shape[-2:], sigma=self.warp_sigma, grid_size=self.warp_grid_size) x = apply_warp(x, warp_field, interpolator=sitk.sitkLinear, fill_mode=self.fill_mode, fill_constant=self.cval) if y is not None: y = np.round( apply_warp(y, warp_field, interpolator=sitk.sitkNearestNeighbor, fill_mode=self.fill_mode, fill_constant=self.void_label)) # Crop # TODO: tf compatible??? crop = list(self.crop_size) if self.crop_size else None if crop: # print ('X before: ' + str(x.shape)) # print ('Y before: ' + str(y.shape)) # print ('Crop_size: ' + str(self.crop_size)) h, w = x.shape[img_row_index], x.shape[img_col_index] # Padd image if it is smaller than the crop size if h < crop[0]: total_pad = crop[0] - h pad_h1 = total_pad / 2 pad_h2 = total_pad - pad_h1 if w < crop[1]: total_pad = crop[1] - w pad_w1 = total_pad / 2 pad_w2 = total_pad - pad_w1 if h < crop[0] or w < crop[1]: x = np.lib.pad(x, ((0, 0), (pad_h1, pad_h2), (pad_w1, pad_w2)), 'constant') y = np.lib.pad(y, ((0, 0), (pad_h1, pad_h2), (pad_w1, pad_w2)), 'constant', constant_values=self.void_label) h, w = x.shape[img_row_index], x.shape[img_col_index] # print ('New size X: ' + str(x.shape)) # print ('New size Y: ' + str(y.shape)) # exit() if crop[0] < h: top = np.random.randint(h - crop[0]) else: #print('Data augmentation: Crop height >= image size') top, crop[0] = 0, h if crop[1] < w: left = np.random.randint(w - crop[1]) else: #print('Data augmentation: Crop width >= image size') left, crop[1] = 0, w if self.dim_ordering == 'th': x = x[..., :, top:top + crop[0], left:left + crop[1]] if y is not None: y = y[..., :, top:top + crop[0], left:left + crop[1]] else: x = x[..., top:top + crop[0], left:left + crop[1], :] if y is not None: y = y[..., top:top + crop[0], left:left + crop[1], :] # print ('X after: ' + str(x.shape)) # print ('Y after: ' + str(y.shape)) # TODO: # channel-wise normalization # barrel/fisheye if y is None: return x else: return x, y
def random_transform(x, dim_ordering='tf', rotation_range=0., width_shift_range=0., height_shift_range=0., shear_range=0., zoom_range=0., channel_shift_range=0., fill_mode='nearest', cval=0., horizontal_flip=False, vertical_flip=False, seed=None, **kwargs): """Randomly augment a single image tensor. # Arguments x: 3D tensor, single image. # Returns A randomly transformed version of the input (same shape). """ x = x.astype('float32') # x is a single image, so it doesn't have image number at index 0 if dim_ordering == 'th': img_channel_axis = 0 img_row_axis = 1 img_col_axis = 2 if dim_ordering == 'tf': img_channel_axis = 2 img_row_axis = 0 img_col_axis = 1 if seed is not None: np.random.seed(seed) if np.isscalar(zoom_range): zoom_range = [1 - zoom_range, 1 + zoom_range] elif len(zoom_range) == 2: zoom_range = [zoom_range[0], zoom_range[1]] else: raise ValueError( '`zoom_range` should be a float or ' 'a tuple or list of two floats. ' 'Received arg: ', zoom_range) # use composition of homographies # to generate final transform that needs to be applied if rotation_range: theta = np.deg2rad(np.random.uniform(rotation_range, rotation_range)) else: theta = 0 if height_shift_range: tx = np.random.uniform(-height_shift_range, height_shift_range) if height_shift_range < 1: tx *= x.shape[img_row_axis] else: tx = 0 if width_shift_range: ty = np.random.uniform(-width_shift_range, width_shift_range) if width_shift_range < 1: ty *= x.shape[img_col_axis] else: ty = 0 if shear_range: shear = np.deg2rad(np.random.uniform(shear_range, shear_range)) else: shear = 0 if zoom_range[0] == 1 and zoom_range[1] == 1: zx, zy = 1, 1 else: zx, zy = np.random.uniform(zoom_range[0], 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=fill_mode, cval=cval) if channel_shift_range != 0: x = image.random_channel_shift(x, channel_shift_range, img_channel_axis) if horizontal_flip: if np.random.random() < 0.5: x = image.flip_axis(x, img_col_axis) if vertical_flip: if np.random.random() < 0.5: x = image.flip_axis(x, img_row_axis) return x
def random_transform(self, x, y): # x is a single image, so it doesn't have image number at index 0 img_row_index = self.row_index - 1 img_col_index = self.col_index - 1 img_channel_index = self.channel_index - 1 if self.crop_mode == 'none': crop_size = (x.shape[img_row_index], x.shape[img_col_index]) else: crop_size = self.crop_size assert x.shape[img_row_index] == y.shape[img_row_index] and x.shape[ img_col_index] == y.shape[ img_col_index], 'DATA ERROR: Different shape of data and label!\ndata shape: %s, label shape: %s' % ( str(x.shape), str(y.shape)) # 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: # * x.shape[img_row_index] tx = np.random.uniform(-self.height_shift_range, self.height_shift_range) * crop_size[0] else: tx = 0 if self.width_shift_range: # * x.shape[img_col_index] ty = np.random.uniform(-self.width_shift_range, self.width_shift_range) * crop_size[1] 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) if self.zoom_maintain_shape: zy = zx 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 = x.shape[img_row_index], x.shape[img_col_index] transform_matrix = transform_matrix_offset_center( transform_matrix, h, w) x = apply_transform(x, transform_matrix, img_channel_index, fill_mode=self.fill_mode, cval=self.cval) y = apply_transform(y, transform_matrix, img_channel_index, fill_mode='constant', cval=self.label_cval) if self.channel_shift_range != 0: x = random_channel_shift(x, self.channel_shift_range, img_channel_index) if self.horizontal_flip: if np.random.random() < 0.5: x = flip_axis(x, img_col_index) y = flip_axis(y, img_col_index) if self.vertical_flip: if np.random.random() < 0.5: x = flip_axis(x, img_row_index) y = flip_axis(y, img_row_index) if self.crop_mode == 'center': x, y = pair_center_crop(x, y, self.crop_size, self.data_format) elif self.crop_mode == 'random': x, y = pair_random_crop(x, y, self.crop_size, self.data_format) # TODO: # channel-wise normalization # barrel/fisheye 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 """ 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) 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)
def random_transform_two_masks(x, mask1, mask2, rotation_range=None, height_shift_range=None, width_shift_range=None, shear_range=None, zoom_range=None, channel_shift_range=None, horizontal_flip=None, vertical_flip=None, fill_mode='constant', cval=0): """Randomly augment a image tensor and masks. # Arguments x: 3D tensor, single image. # Returns A randomly transformed version of the input (same shape). """ # x is a single image, so it doesn't have image number at index 0 img_row_axis = 0 img_col_axis = 1 img_channel_axis = 2 # use composition of homographies # to generate final transform that needs to be applied if rotation_range: theta = np.pi / 180 * np.random.uniform(-rotation_range, rotation_range) else: theta = 0 if height_shift_range: uniform = np.random.uniform(-height_shift_range, height_shift_range) tx = uniform * x.shape[img_row_axis] tmx1 = uniform * mask1.shape[img_row_axis] tmx2 = uniform * mask2.shape[img_row_axis] else: tx = 0 tmx1 = 0 tmx2 = 0 if width_shift_range: random_uniform = np.random.uniform(-width_shift_range, width_shift_range) ty = random_uniform * x.shape[img_col_axis] tmy1 = random_uniform * mask1.shape[img_col_axis] tmy2 = random_uniform * mask2.shape[img_col_axis] else: ty = 0 tmy1 = 0 tmy2 = 0 if shear_range: shear = np.random.uniform(-shear_range, shear_range) else: shear = 0 if zoom_range[0] == 1 and zoom_range[1] == 1: zx, zy = 1, 1 else: zx, zy = np.random.uniform(zoom_range[0], zoom_range[1], 2) transform_matrix = None transform_matrix_mask1 = None transform_matrix_mask2 = 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 transform_matrix_mask1 = rotation_matrix transform_matrix_mask2 = rotation_matrix if tx != 0 or ty != 0: shift_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]]) shift_matrix_mask1 = np.array([[1, 0, tmx1], [0, 1, tmy1], [0, 0, 1]]) shift_matrix_mask2 = np.array([[1, 0, tmx2], [0, 1, tmy2], [0, 0, 1]]) transform_matrix = shift_matrix if transform_matrix is None else np.dot( transform_matrix, shift_matrix) transform_matrix_mask1 = shift_matrix_mask1 if transform_matrix_mask1 is None else np.dot( transform_matrix_mask1, shift_matrix_mask1) transform_matrix_mask2 = shift_matrix_mask1 if transform_matrix_mask2 is None else np.dot( transform_matrix_mask2, shift_matrix_mask2) 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) transform_matrix_mask1 = shear_matrix if transform_matrix_mask1 is None else np.dot( transform_matrix_mask1, shear_matrix) transform_matrix_mask2 = shear_matrix if transform_matrix_mask2 is None else np.dot( transform_matrix_mask2, 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) transform_matrix_mask1 = zoom_matrix if transform_matrix_mask1 is None else np.dot( transform_matrix_mask1, zoom_matrix) transform_matrix_mask2 = zoom_matrix if transform_matrix_mask2 is None else np.dot( transform_matrix_mask2, zoom_matrix) if transform_matrix is not None: h, w = x.shape[img_row_axis], x.shape[img_col_axis] transform_matrix = transform_matrix_offset_center( transform_matrix, h, w) x = apply_transform(x, transform_matrix, img_channel_axis, fill_mode=fill_mode, cval=cval) if transform_matrix_mask1 is not None: h, w = mask1.shape[img_row_axis], mask1.shape[img_col_axis] transform_matrix_mask1 = transform_matrix_offset_center( transform_matrix_mask1, h, w) mask1[:, :, 0:1] = apply_transform(mask1[:, :, 0:1], transform_matrix_mask1, img_channel_axis, fill_mode='constant', cval=0.) if transform_matrix_mask2 is not None: h, w = mask2.shape[img_row_axis], mask2.shape[img_col_axis] transform_matrix_mask2 = transform_matrix_offset_center( transform_matrix_mask2, h, w) mask2[:, :, 0:1] = apply_transform(mask2[:, :, 0:1], transform_matrix_mask2, img_channel_axis, fill_mode='constant', cval=0.) if channel_shift_range != 0: x = random_channel_shift(x, channel_shift_range, img_channel_axis) if horizontal_flip: if np.random.random() < 0.5: x = flip_axis(x, img_col_axis) mask1 = flip_axis(mask1, img_col_axis) mask2 = flip_axis(mask2, img_col_axis) if vertical_flip: if np.random.random() < 0.5: x = flip_axis(x, img_row_axis) mask1 = flip_axis(mask1, img_row_axis) mask2 = flip_axis(mask2, img_row_axis) return x, mask1, mask2
def transform_batch(image_batch, label_batch, horizontal_flip=False, rotation_range=0., channel_shift_range=0., samplewise_std_normalization=False, samplewise_center=False): shape = image_batch.shape img_channel_index = 2 img_row_index = 0 img_col_index = 1 if shape[1] > shape[2]: img_row_index = 1 img_col_index = 0 length = len(image_batch) for i in range(0, length): curr_image = image_batch[i] curr_label = label_batch[i] # Horizontal flip if horizontal_flip: if np.random.random() < 0.5: axis = img_col_index curr_image = np.asarray(curr_image).swapaxes(axis, 0) curr_image = curr_image[::-1, ...] curr_image = curr_image.swapaxes(0, axis) curr_label = np.asarray(curr_label).swapaxes(axis, 0) curr_label = curr_label[::-1, ...] curr_label = curr_label.swapaxes(0, axis) # Rotation if rotation_range != 0.: theta = np.pi / 180 * 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]]) curr_label = im.apply_transform(curr_label, rotation_matrix, channel_axis=img_channel_index) curr_image = im.apply_transform(curr_image, rotation_matrix, channel_axis=img_channel_index) # Channel shift if channel_shift_range != 0.: curr_image = im.random_channel_shift( curr_image, channel_shift_range, channel_axis=img_channel_index) # Normalization if samplewise_std_normalization: if not samplewise_center: samplewise_center = True if samplewise_center: curr_image -= np.mean(curr_image, keepdims=True) if samplewise_std_normalization: curr_image /= (np.std(curr_image, keepdims=True) + epsilon()) image_batch[i] = curr_image label_batch[i] = curr_label # blend_images(images=image_batch, labels=label_batch, folder_url='../datas/images_camvid/output/') return image_batch, label_batch
def random_transform(self, x, y, row_index=1, col_index=2, channel_index=0): if self.horizontal_flip: if True or np.random.random() < 0.5: x = flip_axis(x, 2) y = flip_axis(y, 2) # 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) * x.shape[row_index] else: tx = 0 if self.width_shift_range: ty = np.random.uniform(-self.width_shift_range, self.width_shift_range) * x.shape[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 = x.shape[row_index], x.shape[col_index] transform_matrix = transform_matrix_offset_center( transform_matrix, h, w) x = apply_transform(x, transform_matrix, channel_index, fill_mode='constant') y = apply_transform(y, transform_matrix, channel_index, fill_mode='constant') # if self.vertical_flip: if np.random.random() < 0.5: x = flip_axis(x, 1) y = flip_axis(y, 1) if self.channel_shift_range != 0: x = random_channel_shift(x, self.channel_shift_range) if self.elastic is not None: x, y = elastic_transform(x.reshape(h, w), y.reshape(h, w), *self.elastic) x, y = x.reshape(1, h, w), y.reshape(1, h, w) return x, y
def random_transform_pair(self, x, y, seed=None): """Randomly augment a single image tensor. # Arguments x: 3D tensor, single image. seed: random seed. # Returns A randomly transformed version of the input (same shape). """ # x is a single image, so it doesn't have image number at index 0 img_row_axis = self.row_axis - 1 img_col_axis = self.col_axis - 1 img_channel_axis = self.channel_axis - 1 if seed is not None: np.random.seed(seed) # 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 = transform_matrix_offset_center( transform_matrix, h, w) x = apply_transform(x, transform_matrix, img_channel_axis, fill_mode=self.fill_mode, cval=self.cval) y = apply_transform(y, transform_matrix, img_channel_axis, fill_mode=self.fill_mode, cval=self.cval) if self.channel_shift_range != 0: x = random_channel_shift(x, self.channel_shift_range, img_channel_axis) return x, y
def random_transform(self, x, y): # x is a single image, so it doesn't have image number at index 0 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) * x.shape[img_row_index] else: tx = 0 if self.width_shift_range: ty = np.random.uniform( -self.width_shift_range, self.width_shift_range) * x.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 = x.shape[img_row_index], x.shape[img_col_index] transform_matrix = transform_matrix_offset_center( transform_matrix, h, w) x = apply_transform(x, transform_matrix, img_channel_index, fill_mode=self.fill_mode, cval=self.cval) y = apply_transform(y, transform_matrix, img_channel_index, fill_mode=self.fill_mode, cval=self.cval) if self.channel_shift_range != 0: x = random_channel_shift(x, self.channel_shift_range, img_channel_index) # don't do y channel shift if self.horizontal_flip: if np.random.random() < 0.5: x = flip_axis(x, img_col_index) y = flip_axis(y, img_col_index) if self.vertical_flip: if np.random.random() < 0.5: x = flip_axis(x, img_row_index) y = flip_axis(y, img_row_index) # TODO: # channel-wise normalization # barrel/fisheye return x, y