Skip to content

Add sobel_edges to keras.ops.image#22334

Open
rstar327 wants to merge 4 commits intokeras-team:masterfrom
rstar327:add-sobel-edges-op
Open

Add sobel_edges to keras.ops.image#22334
rstar327 wants to merge 4 commits intokeras-team:masterfrom
rstar327:add-sobel-edges-op

Conversation

@rstar327
Copy link
Contributor

@rstar327 rstar327 commented Mar 3, 2026

Adds keras.ops.image.sobel_edges for computing Sobel edge detection on images. Applies horizontal and vertical Sobel filters, appending a trailing dimension of size 2 (dy and dx gradients). Supports all backends (NumPy, TensorFlow, JAX, Torch; OpenVINO raises NotImplementedError), both data formats, and 3D/4D inputs.

Fixes #22148

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, 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 Keras's image processing capabilities by adding a robust Sobel edge detection function. This new utility allows users to easily identify edges in images across various backends and input configurations, providing a fundamental tool for computer vision tasks. The implementation ensures consistent behavior and output structure, streamlining image gradient computations within the Keras ecosystem.

Highlights

  • New sobel_edges operation: Introduced keras.ops.image.sobel_edges for computing Sobel edge detection, which applies horizontal and vertical Sobel filters to images.
  • Backend Support: The new operation supports NumPy, TensorFlow, JAX, and Torch backends, with OpenVINO explicitly raising a NotImplementedError.
  • Input Flexibility: The sobel_edges function handles both 3D (single image) and 4D (batch of images) inputs, as well as both 'channels_first' and 'channels_last' data formats.
  • Output Format: The output tensor includes an additional trailing dimension of size 2, representing the vertical (dy) and horizontal (dx) gradients.

🧠 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.

Changelog
  • keras/api/_tf_keras/keras/ops/image/init.py
    • Added import for sobel_edges.
  • keras/api/ops/image/init.py
    • Added import for sobel_edges.
  • keras/src/backend/jax/image.py
    • Implemented the sobel_edges function for the JAX backend, including input validation, data format handling, padding, and gradient calculation.
  • keras/src/backend/numpy/image.py
    • Implemented the sobel_edges function for the NumPy backend, handling input conversion, data format, padding, and gradient computation.
  • keras/src/backend/openvino/excluded_concrete_tests.txt
    • Added ImageOpsBehaviorTests::test_sobel_edges, ImageOpsCorrectnessTest::test_sobel_edges, and ImageOpsDtypeTest::test_sobel_edges to the list of excluded tests for the OpenVINO backend.
  • keras/src/backend/openvino/image.py
    • Added a placeholder sobel_edges function that raises a NotImplementedError for the OpenVINO backend.
  • keras/src/backend/tensorflow/image.py
    • Implemented the sobel_edges function for the TensorFlow backend, leveraging tf.image.sobel_edges and handling data format and input rank.
  • keras/src/backend/torch/image.py
    • Implemented the sobel_edges function for the PyTorch backend, including input validation, data format handling, padding, and gradient calculation.
  • keras/src/ops/image.py
    • Added the SobelEdges Operation class.
    • Added the sobel_edges functional API with comprehensive docstrings and examples, integrating with the backend implementation.
  • keras/src/ops/image_test.py
    • Added symbolic tests for sobel_edges to verify output shape for 'channels_last' and 'channels_first' formats.
    • Added concrete tests for sobel_edges to verify output shape for batch and single images, different data formats, and a basic edge detection pattern.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces keras.ops.image.sobel_edges for Sobel edge detection, with implementations for JAX, NumPy, PyTorch, and TensorFlow backends. The changes are well-structured, including appropriate docstrings and tests. My feedback includes minor readability improvements for the manual Sobel filter implementations and suggestions to enhance test coverage for more robust validation.

Note: Security Review did not run due to the size of the PR.

Comment on lines +1937 to +1944
# Test edge detection on known pattern: vertical edge
backend.set_image_data_format("channels_last")
img = np.zeros((1, 5, 5, 1), dtype="float32")
img[0, :, 3:, 0] = 1.0
result = kimage.sobel_edges(img, data_format="channels_last")
dx = result[0, :, :, 0, 1]
# The horizontal gradient should be non-zero near the edge
self.assertTrue(np.any(np.abs(np.array(dx)) > 0))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To make this test more robust, you could also assert that the vertical gradient dy is zero for a vertical edge. Additionally, adding a similar test case for a horizontal edge would improve test coverage by verifying both dx and dy responses for basic patterns.

        # Test edge detection on known pattern: vertical edge
        backend.set_image_data_format("channels_last")
        img = np.zeros((1, 5, 5, 1), dtype="float32")
        img[0, :, 3:, 0] = 1.0
        result = kimage.sobel_edges(img, data_format="channels_last")
        dy = result[0, :, :, 0, 0]
        dx = result[0, :, :, 0, 1]
        # The horizontal gradient should be non-zero near the edge.
        self.assertTrue(np.any(np.abs(np.array(dx)) > 0))
        # The vertical gradient should be zero for a vertical edge.
        self.assertAllClose(dy, np.zeros_like(dy))

        # Test edge detection on known pattern: horizontal edge
        img = np.zeros((1, 5, 5, 1), dtype="float32")
        img[0, 3:, :, 0] = 1.0
        result = kimage.sobel_edges(img, data_format="channels_last")
        dy = result[0, :, :, 0, 0]
        dx = result[0, :, :, 0, 1]
        # The vertical gradient should be non-zero near the edge.
        self.assertTrue(np.any(np.abs(np.array(dy)) > 0))
        # The horizontal gradient should be zero for a horizontal edge.
        self.assertAllClose(dx, np.zeros_like(dx))

rstar327 and others added 3 commits March 3, 2026 04:07
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@codecov-commenter
Copy link

codecov-commenter commented Mar 3, 2026

Codecov Report

❌ Patch coverage is 88.57143% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.86%. Comparing base (e0698d2) to head (2b3ab2d).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
keras/src/ops/image.py 80.00% 2 Missing and 1 partial ⚠️
keras/src/backend/jax/image.py 90.90% 1 Missing and 1 partial ⚠️
keras/src/backend/numpy/image.py 91.30% 1 Missing and 1 partial ⚠️
keras/src/backend/tensorflow/image.py 89.47% 1 Missing and 1 partial ⚠️
keras/src/backend/torch/image.py 91.30% 1 Missing and 1 partial ⚠️
keras/api/_tf_keras/keras/ops/image/__init__.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           master   #22334    +/-   ##
========================================
  Coverage   82.85%   82.86%            
========================================
  Files         594      594            
  Lines       65732    65837   +105     
  Branches    10266    10288    +22     
========================================
+ Hits        54462    54555    +93     
- Misses       8650     8657     +7     
- Partials     2620     2625     +5     
Flag Coverage Δ
keras 82.69% <88.57%> (+<0.01%) ⬆️
keras-jax 60.87% <34.28%> (-0.05%) ⬇️
keras-numpy 55.08% <35.23%> (-0.03%) ⬇️
keras-openvino 49.01% <14.28%> (-0.06%) ⬇️
keras-tensorflow 62.11% <31.42%> (-0.05%) ⬇️
keras-torch 60.98% <35.23%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add sobel_edges to keras.ops.image

3 participants