Add comprehensive unit tests for image processing functions#22513
Add comprehensive unit tests for image processing functions#22513xingzihai wants to merge 1 commit intokeras-team:masterfrom
Conversation
This commit adds extensive test coverage for keras.ops.image functions: - RGBToGrayscaleEdgeCasesTest: Edge cases for rgb_to_grayscale including single pixel, all black/white images, pure colors, relative brightness, uint8 support, and batch consistency - RGBHSVRoundTripTest: Round-trip conversion tests between RGB and HSV including identity, pure colors (red, green, blue), grayscale colors - ResizeEdgeCasesTest: Edge cases for resize including single pixel, identity resize, large up/down sampling, non-square, aspect ratio preservation, and invalid size handling - AffineTransformEdgeCasesTest: Edge cases for affine_transform including identity transform, translation, small images, single pixel, batched transforms - PadImagesEdgeCasesTest: Edge cases for pad_images including zero padding, asymmetric padding, single pixel, large padding, target dimensions, and error handling for invalid inputs - CropImagesEdgeCasesTest: Edge cases for crop_images including zero cropping, asymmetric cropping, target dimensions, minimum crop, and error handling - GaussianBlurEdgeCasesTest: Edge cases for gaussian_blur including small and large sigma, asymmetric kernels, single pixel, mean preservation, uniform image handling - ElasticTransformEdgeCasesTest: Edge cases for elastic_transform including zero/small alpha, reproducibility with seed, different seeds, small images - PerspectiveTransformEdgeCasesTest: Edge cases for perspective_transform including identity transform, small shifts, single pixel - ExtractPatchesEdgeCasesTest: Edge cases for extract_patches including small images, full image coverage, overlapping patches, single pixel - MapCoordinatesEdgeCasesTest: Edge cases for map_coordinates including identity mapping, single pixel, coordinate shift - ScaleAndTranslateEdgeCasesTest: Edge cases for scale_and_translate including identity, small/large scale, translation - ImageOpsInvalidInputTest: Tests for invalid inputs including wrong dtypes, wrong channel counts, invalid size types, conflicting arguments - ImageOpsChannelsFirstEdgeCasesTest: Tests for channels_first data format across all major functions
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the robustness of Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive suite of new test cases for various Keras image manipulation operations, including color conversions (RGB to Grayscale, RGB/HSV round-trip), geometric transformations (resize, affine, perspective, elastic), and utility functions (pad, crop, blur, extract patches, map coordinates, scale/translate). The tests cover edge cases, invalid inputs, and channels_first data format scenarios, significantly enhancing the robustness of the image operations. The review feedback suggests improving the rigor and completeness of several tests by adding more precise assertions for pixel values, content transformation, and output data types, using tighter tolerances for numerical comparisons, and addressing an inconsistency in RGBToGrayscale's input channel validation.
| # at the ops level for RGB conversion (backend handles it) | ||
| out = kimage.rgb_to_grayscale(x) | ||
| self.assertEqual(out.shape, (10, 10, 1)) | ||
|
|
There was a problem hiding this comment.
The RGBToGrayscale operation's compute_output_spec (lines 28-31 in keras/src/ops/image.py) does not validate that the input image has 3 channels, unlike RGBToHSV and HSVToRGB. This inconsistency could lead to unexpected behavior or less informative error messages if a non-3-channel image is passed. It should explicitly check for 3 channels.
| def test_crop_images_with_target_dimensions(self): | ||
| """Test cropping using target dimensions.""" | ||
| x = np.ones((10, 10, 3), dtype="float32") | ||
| out = kimage.crop_images(x, 0, 0, target_height=5, target_width=5) |
| dtype="float32") | ||
| end_points = np.array([[1, 1], [0, 10], [10, 0], [10, 10]], | ||
| dtype="float32") | ||
| out = kimage.perspective_transform(x, start_points, end_points) |
| out = kimage.resize(x, (5, 5)) | ||
| self.assertEqual(out.shape, (5, 5, 3)) | ||
| # Values should be very close (not exact due to interpolation) | ||
| self.assertTrue(np.allclose(x, out, atol=0.1)) |
| x = np.repeat(np.repeat(x, 10, axis=0), 10, axis=1) | ||
| out = kimage.resize(x, (5, 5)) | ||
| # Values should still be in valid uint8 range | ||
| self.assertTrue(np.all(out >= 0)) |
| out = kimage.rgb_to_grayscale(x) | ||
| self.assertEqual(out.shape, (1, 1, 1)) | ||
| # Red channel has weight 0.299 in standard conversion | ||
| self.assertTrue(out[0, 0, 0] > 0.28 and out[0, 0, 0] < 0.31) |
There was a problem hiding this comment.
| [[1.0, 1.0], [2.0, 2.0]], | ||
| [[0.0, 0.0], [0.0, 0.0]] | ||
| ], dtype="float32") | ||
| out = kimage.map_coordinates(x, coords, order=0) |
| spatial_dims=(0, 1), | ||
| method="linear" | ||
| ) | ||
| self.assertEqual(out.shape, (10, 10, 3)) |
| spatial_dims=(0, 1), | ||
| method="linear" | ||
| ) | ||
| self.assertEqual(out.shape, (10, 10, 3)) |
| """Test conversion with uint8 dtype.""" | ||
| x = np.random.randint(0, 256, (10, 10, 3), dtype="uint8") | ||
| out = kimage.rgb_to_grayscale(x) | ||
| self.assertEqual(out.shape, (10, 10, 1)) |
Codecov Report✅ All modified and coverable lines are covered by tests.
Additional details and impacted files@@ Coverage Diff @@
## master #22513 +/- ##
===========================================
- Coverage 83.20% 24.94% -58.27%
===========================================
Files 596 596
Lines 67621 67621
Branches 10531 10531
===========================================
- Hits 56266 16866 -39400
- Misses 8630 49885 +41255
+ Partials 2725 870 -1855
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
hertschuh
left a comment
There was a problem hiding this comment.
Please also approve the CLA
| self.assertEqual(patches.shape, expected_shape) | ||
|
|
||
|
|
||
| class RGBToGrayscaleEdgeCasesTest(testing.TestCase): |
There was a problem hiding this comment.
These tests significantly overlap the existing ones. Most of them can be removed.
Additionally, these tests should be interspersed with the existing ones so that all tests for the same method are grouped together.
Summary
This PR adds extensive test coverage for
keras.ops.imagefunctions, focusing on edge cases, invalid inputs, round-trip conversions, and data type handling that were not covered by existing tests.Changes
Added 14 new test classes with 894 lines of test code:
New Test Classes
RGBToGrayscaleEdgeCasesTest (10 tests)
RGBHSVRoundTripTest (9 tests)
ResizeEdgeCasesTest (10 tests)
AffineTransformEdgeCasesTest (5 tests)
PadImagesEdgeCasesTest (8 tests)
CropImagesEdgeCasesTest (7 tests)
GaussianBlurEdgeCasesTest (6 tests)
ElasticTransformEdgeCasesTest (5 tests)
PerspectiveTransformEdgeCasesTest (3 tests)
ExtractPatchesEdgeCasesTest (4 tests)
MapCoordinatesEdgeCasesTest (3 tests)
ScaleAndTranslateEdgeCasesTest (4 tests)
ImageOpsInvalidInputTest (7 tests)
ImageOpsChannelsFirstEdgeCasesTest (7 tests)
Testing
All tests follow the existing test patterns in the repository:
testing.TestCasebase classChecklist
image_test.py