Skip to content

Commit

Permalink
Adjust value_range for random_contrast and random_hue (#20671)
Browse files Browse the repository at this point in the history
* Adjust value_range for random_contrast and random_hue

* Add value_range description

* Correct failed test cases
  • Loading branch information
shashaka authored Dec 19, 2024
1 parent 84b531c commit 2db547b
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,19 @@ class RandomContrast(BaseImagePreprocessingLayer):
`[1.0 - lower, 1.0 + upper]`. For any pixel x in the channel,
the output will be `(x - mean) * factor + mean`
where `mean` is the mean value of the channel.
value_range: the range of values the incoming images will have.
Represented as a two-number tuple written `[low, high]`. This is
typically either `[0, 1]` or `[0, 255]` depending on how your
preprocessing pipeline is set up.
seed: Integer. Used to create a random seed.
"""

_FACTOR_BOUNDS = (0, 1)

def __init__(self, factor, seed=None, **kwargs):
def __init__(self, factor, value_range=(0, 255), seed=None, **kwargs):
super().__init__(**kwargs)
self._set_factor(factor)
self.value_range = value_range
self.seed = seed
self.generator = SeedGenerator(seed)

Expand Down Expand Up @@ -89,7 +94,9 @@ def transform_images(self, images, transformation, training=True):
if training:
constrast_factor = transformation["contrast_factor"]
outputs = self._adjust_constrast(images, constrast_factor)
outputs = self.backend.numpy.clip(outputs, 0, 255)
outputs = self.backend.numpy.clip(
outputs, self.value_range[0], self.value_range[1]
)
self.backend.numpy.reshape(outputs, self.backend.shape(images))
return outputs
return images
Expand Down Expand Up @@ -135,6 +142,7 @@ def compute_output_shape(self, input_shape):
def get_config(self):
config = {
"factor": self.factor,
"value_range": self.value_range,
"seed": self.seed,
}
base_config = super().get_config()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def test_layer(self):
layers.RandomContrast,
init_kwargs={
"factor": 0.75,
"value_range": (0, 255),
"seed": 1,
},
input_shape=(8, 3, 4, 3),
Expand All @@ -24,6 +25,7 @@ def test_layer(self):
layers.RandomContrast,
init_kwargs={
"factor": 0.75,
"value_range": (0, 255),
"seed": 1,
"data_format": "channels_first",
},
Expand All @@ -32,21 +34,67 @@ def test_layer(self):
expected_output_shape=(8, 3, 4, 4),
)

def test_random_contrast(self):
def test_random_contrast_with_value_range_0_to_255(self):
seed = 9809
np.random.seed(seed)
inputs = np.random.random((12, 8, 16, 3))
layer = layers.RandomContrast(factor=0.5, seed=seed)
outputs = layer(inputs)

data_format = backend.config.image_data_format()
if data_format == "channels_last":
inputs = np.random.random((12, 8, 16, 3))
height_axis = -3
width_axis = -2
else:
inputs = np.random.random((12, 3, 8, 16))
height_axis = -2
width_axis = -1

inputs = backend.convert_to_tensor(inputs, dtype="float32")
layer = layers.RandomContrast(
factor=0.5, value_range=(0, 255), seed=seed
)
transformation = layer.get_random_transformation(inputs, training=True)
outputs = layer.transform_images(inputs, transformation, training=True)

# Actual contrast arithmetic
np.random.seed(seed)
factor = backend.convert_to_numpy(transformation["contrast_factor"])
inputs = backend.convert_to_numpy(inputs)
inp_mean = np.mean(inputs, axis=height_axis, keepdims=True)
inp_mean = np.mean(inp_mean, axis=width_axis, keepdims=True)
actual_outputs = (inputs - inp_mean) * factor + inp_mean
outputs = backend.convert_to_numpy(outputs)
actual_outputs = np.clip(actual_outputs, 0, 255)

self.assertAllClose(outputs, actual_outputs)

def test_random_contrast_with_value_range_0_to_1(self):
seed = 9809
np.random.seed(seed)

data_format = backend.config.image_data_format()
if data_format == "channels_last":
inputs = np.random.random((12, 8, 16, 3))
height_axis = -3
width_axis = -2
else:
inputs = np.random.random((12, 3, 8, 16))
height_axis = -2
width_axis = -1

inputs = backend.convert_to_tensor(inputs, dtype="float32")
layer = layers.RandomContrast(factor=0.5, value_range=(0, 1), seed=seed)
transformation = layer.get_random_transformation(inputs, training=True)
outputs = layer.transform_images(inputs, transformation, training=True)

# Actual contrast arithmetic
np.random.seed(seed)
factor = np.random.uniform(0.5, 1.5)
inp_mean = np.mean(inputs, axis=-3, keepdims=True)
inp_mean = np.mean(inp_mean, axis=-2, keepdims=True)
factor = backend.convert_to_numpy(transformation["contrast_factor"])
inputs = backend.convert_to_numpy(inputs)
inp_mean = np.mean(inputs, axis=height_axis, keepdims=True)
inp_mean = np.mean(inp_mean, axis=width_axis, keepdims=True)
actual_outputs = (inputs - inp_mean) * factor + inp_mean
outputs = backend.convert_to_numpy(outputs)
actual_outputs = np.clip(outputs, 0, 255)
actual_outputs = np.clip(actual_outputs, 0, 1)

self.assertAllClose(outputs, actual_outputs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ class RandomHue(BaseImagePreprocessingLayer):
_FACTOR_BOUNDS = (0, 1)

def __init__(
self, factor, value_range, data_format=None, seed=None, **kwargs
self,
factor,
value_range=(0, 255),
data_format=None,
seed=None,
**kwargs,
):
super().__init__(data_format=data_format, **kwargs)
self._set_factor(factor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,24 @@ def test_random_hue_inference(self):
output = layer(inputs, training=False)
self.assertAllClose(inputs, output)

def test_random_hue_value_range(self):
def test_random_hue_value_range_0_to_1(self):
image = keras.random.uniform(shape=(3, 3, 3), minval=0, maxval=1)

layer = layers.RandomHue(0.2, (0, 255))
layer = layers.RandomHue(0.2, (0, 1))
adjusted_image = layer(image)

self.assertTrue(keras.ops.numpy.all(adjusted_image >= 0))
self.assertTrue(keras.ops.numpy.all(adjusted_image <= 1))

def test_random_hue_value_range_0_to_255(self):
image = keras.random.uniform(shape=(3, 3, 3), minval=0, maxval=255)

layer = layers.RandomHue(0.2, (0, 255))
adjusted_image = layer(image)

self.assertTrue(keras.ops.numpy.all(adjusted_image >= 0))
self.assertTrue(keras.ops.numpy.all(adjusted_image <= 255))

def test_random_hue_no_change_with_zero_factor(self):
data_format = backend.config.image_data_format()
if data_format == "channels_last":
Expand Down

0 comments on commit 2db547b

Please sign in to comment.