diff --git a/keras/src/layers/preprocessing/image_preprocessing/resizing.py b/keras/src/layers/preprocessing/image_preprocessing/resizing.py index 83460175ee54..977fa4cf7694 100644 --- a/keras/src/layers/preprocessing/image_preprocessing/resizing.py +++ b/keras/src/layers/preprocessing/image_preprocessing/resizing.py @@ -101,6 +101,21 @@ def __init__( self.width_axis = -2 def transform_images(self, images, transformation=None, training=True): + # Compute effective crop flag: + # only crop if aspect ratios differ and flag is True + input_height, input_width = transformation + epsilon = self.backend.epsilon() + source_aspect_ratio = input_width / (input_height + epsilon) + target_aspect_ratio = self.width / (self.height + epsilon) + + # Use a small epsilon for floating-point comparison + aspect_ratios_match = ( + abs(source_aspect_ratio - target_aspect_ratio) < 1e-6 + ) + effective_crop_to_aspect_ratio = ( + self.crop_to_aspect_ratio and not aspect_ratios_match + ) + size = (self.height, self.width) resized = self.backend.image.resize( images, @@ -108,7 +123,7 @@ def transform_images(self, images, transformation=None, training=True): interpolation=self.interpolation, antialias=self.antialias, data_format=self.data_format, - crop_to_aspect_ratio=self.crop_to_aspect_ratio, + crop_to_aspect_ratio=effective_crop_to_aspect_ratio, pad_to_aspect_ratio=self.pad_to_aspect_ratio, fill_mode=self.fill_mode, fill_value=self.fill_value, diff --git a/keras/src/layers/preprocessing/image_preprocessing/resizing_test.py b/keras/src/layers/preprocessing/image_preprocessing/resizing_test.py index 38dfafbeaab0..6f465adb17ac 100644 --- a/keras/src/layers/preprocessing/image_preprocessing/resizing_test.py +++ b/keras/src/layers/preprocessing/image_preprocessing/resizing_test.py @@ -124,6 +124,31 @@ def test_crop_to_aspect_ratio(self, data_format): ref_out = ref_out.transpose(0, 3, 1, 2) self.assertAllClose(ref_out, out) + @parameterized.parameters([("channels_first",), ("channels_last",)]) + def test_crop_to_aspect_ratio_no_op_when_aspects_match(self, data_format): + # Test that crop_to_aspect_ratio=True behaves identically to False + # when source and target aspect ratios match (no cropping should occur). + img = np.reshape(np.arange(0, 16), (1, 4, 4, 1)).astype("float32") + if data_format == "channels_first": + img = img.transpose(0, 3, 1, 2) + out_false = layers.Resizing( + height=2, + width=2, + interpolation="nearest", + data_format=data_format, + crop_to_aspect_ratio=False, + )(img) + out_true = layers.Resizing( + height=2, + width=2, + interpolation="nearest", + data_format=data_format, + crop_to_aspect_ratio=True, + )(img) + # Outputs should be identical when aspect ratios match + # (4:4 -> 2:2, both 1:1). + self.assertAllClose(out_false, out_true) + @parameterized.parameters([("channels_first",), ("channels_last",)]) def test_unbatched_image(self, data_format): img = np.reshape(np.arange(0, 16), (4, 4, 1)).astype("float32")