def test_transform_data_types(self): for dtype in _DTYPES: image = tf.constant([[1, 2], [3, 4]], dtype=dtype) self.assertAllEqual( np.array([[4, 4], [4, 4]]).astype(dtype.as_numpy_dtype), transform_ops.transform(image, [1] * 8), )
def test_transform_static_output_shape(self): image = tf.constant([[1., 2.], [3., 4.]]) result = transform_ops.transform( image, tf.random.uniform([8], -1, 1), output_shape=tf.constant([3, 5])) self.assertAllEqual([3, 5], result.shape)
def transform_fn(x): x.set_shape(input_shape) transform = transform_ops.angles_to_projective_transforms( np.pi / 2, 4, 4) return transform_ops.transform(images=x, transforms=transform, output_shape=resize_shape)
def test_transform_constant_fill_mode(dtype, fill_value): if fill_value != 0.0 and LooseVersion( tf.__version__) < LooseVersion("2.4.0"): pytest.skip( "Nonzero fill_value is not supported for TensorFlow < 2.4.0.") image = tf.constant( [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]], dtype=dtype) expected = np.asarray( [ [fill_value, 0, 1, 2], [fill_value, 4, 5, 6], [fill_value, 8, 9, 10], [fill_value, 12, 13, 14], ], dtype=dtype.as_numpy_dtype, ) # Translate right by 1 (the transformation matrix is always inverted, # hence the -1). translation = tf.constant([1, 0, -1, 0, 1, 0, 0, 0], dtype=tf.float32) image_transformed = transform_ops.transform( image, translation, fill_mode="constant", fill_value=fill_value, ) np.testing.assert_equal(image_transformed.numpy(), expected)
def _test_grad_different_shape(self, input_shape, output_shape): with self.cached_session(): test_image_shape = input_shape test_image = np.random.randn(*test_image_shape) test_image_tensor = tf.constant(test_image, shape=test_image_shape) test_transform = transform_ops.angles_to_projective_transforms( np.pi / 2, 4, 4) if len(output_shape) == 2: resize_shape = output_shape elif len(output_shape) == 3: resize_shape = output_shape[0:2] elif len(output_shape) == 4: resize_shape = output_shape[1:3] output = transform_ops.transform( images=test_image_tensor, transforms=test_transform, output_shape=resize_shape) left_err = gradient_checker.compute_gradient_error( test_image_tensor, test_image_shape, output, output_shape, x_init_value=test_image) self.assertLess(left_err, 1e-10)
def translate(images, translations, interpolation="NEAREST", name=None): """Translate image(s) by the passed vectors(s). Args: images: A tensor of shape (num_images, num_rows, num_columns, num_channels) (NHWC), (num_rows, num_columns, num_channels) (HWC), or (num_rows, num_columns) (HW). The rank must be statically known (the shape is not `TensorShape(None)`). translations: A vector representing [dx, dy] or (if images has rank 4) a matrix of length num_images, with a [dx, dy] vector for each image in the batch. interpolation: Interpolation mode. Supported values: "NEAREST", "BILINEAR". name: The name of the op. Returns: Image(s) with the same type and shape as `images`, translated by the given vector(s). Empty space due to the translation will be filled with zeros. Raises: TypeError: If `images` is an invalid type. """ with tf.name_scope(name or "translate"): return transform(images, translations_to_projective_transforms(translations), interpolation=interpolation)
def _apply_slant(features: dict, labels=None): image = features['input_images'] height_image = tf.cast(tf.shape(image)[0], dtype=tf.float32) with tf.name_scope('add_slant'): alpha = tf.random.uniform([], -params.data_augmentation_max_slant, params.data_augmentation_max_slant, name='pick_random_slant_angle') shiftx = tf.math.maximum(tf.math.multiply(-alpha, height_image), 0) # Pad in order not to loose image info when transformation is applied x_pad = 0 y_pad = tf.math.round( tf.math.ceil(tf.math.abs(tf.math.multiply(alpha, height_image)))) y_pad = tf.cast(y_pad, dtype=tf.int32) paddings = [[x_pad, x_pad], [y_pad, 0], [0, 0]] transform_matrix = [1, alpha, shiftx, 0, 1, 0, 0, 0] # Apply transformation to image image_pad = tf.pad(image, paddings) image_transformed = transform(image_pad, transform_matrix, interpolation='BILINEAR') # Apply transformation to mask. The mask will be used to retrieve the pixels that have been filled # with zero during transformation and update their value with background value # TODO : Would be better to have some kind of binarization (i.e Otsu) and get the mean background value background_pixel_value = 255 empty = background_pixel_value * tf.ones(tf.shape(image)) empty_pad = tf.pad(empty, paddings) empty_transformed = tf.subtract( tf.cast(background_pixel_value, dtype=tf.int32), tf.cast(transform(empty_pad, transform_matrix, interpolation='NEAREST'), dtype=tf.int32)) # Update additional zeros values with background_pixel_value and cast result to uint8 image = tf.add(tf.cast(image_transformed, dtype=tf.int32), empty_transformed) image = tf.cast(image, tf.uint8) features['input_images'] = image return features, labels if use_labels else features
def test_extreme_projective_transform(dtype): image = tf.constant( [[1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1]], dtype=dtype) transformation = tf.constant([1, 0, 0, 0, 1, 0, -1, 0], tf.dtypes.float32) image_transformed = transform_ops.transform(image, transformation) np.testing.assert_equal( [[1, 0, 0, 0], [0, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 0]], image_transformed.numpy(), )
def test_extreme_projective_transform(self): for dtype in _DTYPES: image = tf.constant( [[1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1]], dtype=dtype) transformation = tf.constant([1, 0, 0, 0, 1, 0, -1, 0], tf.dtypes.float32) image_transformed = transform_ops.transform(image, transformation) self.assertAllEqual( [[1, 0, 0, 0], [0, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 0]], image_transformed)
def test_transform_reflect_fill_mode(dtype): image = tf.constant( [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]], dtype=dtype ) expected = np.asarray( [[0, 0, 1, 2], [4, 4, 5, 6], [8, 8, 9, 10], [12, 12, 13, 14]], dtype=dtype.as_numpy_dtype, ) # Translate right by 1 (the transformation matrix is always inverted, # hence the -1). translation = tf.constant([1, 0, -1, 0, 1, 0, 0, 0], dtype=tf.float32) image_transformed = transform_ops.transform(image, translation, fill_mode="reflect") np.testing.assert_equal(image_transformed.numpy(), expected)
def test_compose_rotate(dtype): image = tf.constant( [[1, 1, 1, 0], [1, 0, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0]], dtype=dtype) # Rotate counter-clockwise by pi / 2. rotation = transform_ops.angles_to_projective_transforms(np.pi / 2, 4, 4) # Translate right by 1 (the transformation matrix is always inverted, # hence the -1). translation = tf.constant([1, 0, -1, 0, 1, 0, 0, 0], dtype=tf.float32) composed = transform_ops.compose_transforms([rotation, translation]) image_transformed = transform_ops.transform(image, composed) np.testing.assert_equal( image_transformed.numpy(), [[0, 0, 0, 0], [0, 1, 0, 1], [0, 1, 0, 1], [0, 1, 1, 1]], )
def translate( images: TensorLike, translations: TensorLike, interpolation: str = "nearest", fill_mode: str = "constant", name: Optional[str] = None, fill_value: TensorLike = 0.0, ) -> tf.Tensor: """Translate image(s) by the passed vectors(s). Args: images: A tensor of shape `(num_images, num_rows, num_columns, num_channels)` (NHWC), `(num_rows, num_columns, num_channels)` (HWC), or `(num_rows, num_columns)` (HW). The rank must be statically known (the shape is not `TensorShape(None)`). translations: A vector representing `[dx, dy]` or (if `images` has rank 4) a matrix of length num_images, with a `[dx, dy]` vector for each image in the batch. interpolation: Interpolation mode. Supported values: "nearest", "bilinear". fill_mode: Points outside the boundaries of the input are filled according to the given mode (one of `{'constant', 'reflect', 'wrap', 'nearest'}`). - *reflect*: `(d c b a | a b c d | d c b a)` The input is extended by reflecting about the edge of the last pixel. - *constant*: `(k k k k | a b c d | k k k k)` The input is extended by filling all values beyond the edge with the same constant value k = 0. - *wrap*: `(a b c d | a b c d | a b c d)` The input is extended by wrapping around to the opposite edge. - *nearest*: `(a a a a | a b c d | d d d d)` The input is extended by the nearest pixel. fill_value: a float represents the value to be filled outside the boundaries when `fill_mode` is "constant". name: The name of the op. Returns: Image(s) with the same type and shape as `images`, translated by the given vector(s). Empty space due to the translation will be filled with zeros. Raises: TypeError: If `images` is an invalid type. """ with tf.name_scope(name or "translate"): return transform( images, translations_to_projective_transforms(translations), interpolation=interpolation, fill_mode=fill_mode, fill_value=fill_value, )
def _test_grad(self, shape_to_test): with self.cached_session(): test_image_shape = shape_to_test test_image = np.random.randn(*test_image_shape) test_image_tensor = tf.constant(test_image, shape=test_image_shape) test_transform = transform_ops.angles_to_projective_transforms( np.pi / 2, 4, 4) output_shape = test_image_shape output = transform_ops.transform(test_image_tensor, test_transform) left_err = gradient_checker.compute_gradient_error( test_image_tensor, test_image_shape, output, output_shape, x_init_value=test_image) self.assertLess(left_err, 1e-10)
def test_compose(self): for dtype in _DTYPES: image = tf.constant( [[1, 1, 1, 0], [1, 0, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0]], dtype=dtype) # Rotate counter-clockwise by pi / 2. rotation = transform_ops.angles_to_projective_transforms( np.pi / 2, 4, 4) # Translate right by 1 (the transformation matrix is always inverted, # hence the -1). translation = tf.constant([1, 0, -1, 0, 1, 0, 0, 0], dtype=tf.dtypes.float32) composed = transform_ops.compose_transforms(rotation, translation) image_transformed = transform_ops.transform(image, composed) self.assertAllEqual( [[0, 0, 0, 0], [0, 1, 0, 1], [0, 1, 0, 1], [0, 1, 1, 1]], image_transformed)
def transform(self, data): """ Transforms the data with the augmentation transformation Args: data: Data to be transformed Returns: Transformed (augmented) data """ transform_matrix_flatten = tf.reshape(self.transform_matrix, shape=[1, 9]) transform_matrix_flatten = transform_matrix_flatten[0, 0:8] #augment_data = tf.contrib.image.transform(data, transform_matrix_flatten) augment_data = transform_ops.transform(data, transform_matrix_flatten) augment_data = tf.cond(self.do_flip_lr_tensor, lambda: tf.image.flip_left_right(augment_data), lambda: augment_data) augment_data = tf.cond(self.do_flip_ud_tensor, lambda: tf.image.flip_up_down(augment_data), lambda: augment_data) return augment_data
def test_transform_data_types(dtype): image = tf.constant([[1, 2], [3, 4]], dtype=dtype) np.testing.assert_equal( np.array([[4, 4], [4, 4]]).astype(dtype.as_numpy_dtype), transform_ops.transform(image, [1] * 8), )
def test_transform_eager(): image = tf.constant([[1.0, 2.0], [3.0, 4.0]]) np.testing.assert_equal( np.array([[4, 4], [4, 4]]), transform_ops.transform(image, [1] * 8) )
def test_transform_static_output_shape(): image = tf.constant([[1.0, 2.0], [3.0, 4.0]]) result = transform_ops.transform( image, tf.random.uniform([8], -1, 1), output_shape=[3, 5] ) np.testing.assert_equal([3, 5], result.shape)
def test_transform_eager(self): image = tf.constant([[1., 2.], [3., 4.]]) self.assertAllEqual( np.array([[4, 4], [4, 4]]), transform_ops.transform( image, [1] * 8))