Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimised gaussian blur transform #2347

Merged

Conversation

vedantdalimkar
Copy link
Contributor

@vedantdalimkar vedantdalimkar commented Feb 18, 2025

Addresses #2293

Optimised gaussian blur at the algorithm level. Made use of the fact that gaussian kernels are separable, which means that convolution with 2D gaussian kernel can be simplified to 2 convolutions with 1D gaussian kernel which reduces the time complexity of the algorithm.

  1. Modified the 2D gaussian kernel creation function to a function that creates 1D gaussian kernel.
  2. Replaced 2D convolution with separable 1D convolution
  3. Added tests for the new 1D gaussian kernel creation function

Time benchmarks -
Old algorithm results -
source_gaussian_blur.txt

Updated algorithm results -
gaussian_blur.txt

Copy link
Contributor

sourcery-ai bot commented Feb 18, 2025

Reviewer's Guide by Sourcery

This pull request optimizes the Gaussian blur transform by utilizing the separable property of Gaussian kernels. It introduces a 1D Gaussian kernel creation function and replaces the 2D convolution with separable convolution, improving the algorithm's time complexity. Additionally, tests were added for the new 1D kernel creation function.

Sequence diagram for Gaussian Blur with Separable Convolution

sequenceDiagram
    participant Image
    participant GaussianBlurTransform
    participant functional.create_gaussian_kernel_1d
    participant functional.seperable_convolve

    Image->>GaussianBlurTransform: apply(image, transform, **params)
    GaussianBlurTransform->>GaussianBlurTransform: get_params_dependent_on_data(params, data)
    GaussianBlurTransform->>functional.create_gaussian_kernel_1d: kernel = create_gaussian_kernel_1d(sigma, ksize)
    functional.create_gaussian_kernel_1d-->>GaussianBlurTransform: kernel
    GaussianBlurTransform->>functional.seperable_convolve: convolve(image, kernel)
    functional.seperable_convolve-->>GaussianBlurTransform: blurred_image
    GaussianBlurTransform-->>Image: blurred_image
Loading

Updated class diagram for Gaussian Blur Transform

classDiagram
    class GaussianBlurTransform {
        -blur_limit: Tuple[int, int]
        -sigma_limit: Tuple[float, float]
        +apply(img: np.ndarray, kernel: np.ndarray, **params: Any) : np.ndarray
        +get_params_dependent_on_data(params: dict[str, Any], data: dict[str, Any]) : dict[str, float]
        +get_transform_init_args_names() : tuple[str, ...]
    }

    class functional {
        +create_gaussian_kernel_1d(sigma: float, ksize: int = 0) : np.ndarray
        +seperable_convolve(img: np.ndarray, kernel: np.ndarray) : np.ndarray
    }

    GaussianBlurTransform --|> functional : uses
Loading

File-Level Changes

Change Details Files
Introduced a function to create a 1D Gaussian kernel.
  • Added create_gaussian_kernel_1d function to generate a 1D Gaussian kernel based on provided sigma and kernel size.
  • Added create_gaussian_kernel_input_array function to generate the input array for the gaussian function.
albumentations/augmentations/blur/functional.py
Added tests for the 1D Gaussian kernel creation function.
  • Added test_1d_kernel_shapes to verify the shape of the generated 1D kernel.
  • Added assertions in test_kernel_normalization to check the normalization of the 1D kernel.
  • Added test_1d_kernel_peak_values to ensure the peak values of the 1D kernel decrease with increasing sigma.
tests/functional/test_blur.py
Replaced 2D convolution with separable convolution.
  • Added seperable_convolve function to perform separable convolution using cv2.sepFilter2D.
  • Modified the apply function in GaussianBlur to use the seperable_convolve function.
  • Modified the get_params_dependent_on_data function in GaussianBlur to use the create_gaussian_kernel_1d function.
albumentations/augmentations/functional.py
albumentations/augmentations/blur/transforms.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @vedantdalimkar - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider adding a test case that compares the output of the original and optimized Gaussian blur implementations to ensure they produce similar results.
  • It might be beneficial to include a performance comparison between the original and optimized Gaussian blur implementations in the pull request description.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟢 Security: all looks good
  • 🟡 Testing: 1 issue found
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@ternaus ternaus merged commit 03d4ceb into albumentations-team:main Feb 18, 2025
14 checks passed
@ternaus
Copy link
Collaborator

ternaus commented Feb 18, 2025

@vedantdalimkar Great job. Really nice optimizations. I did not even know that cv2 has separable convolutions.

@vedantdalimkar
Copy link
Contributor Author

@ternaus Just FYI, using cv2.GuassianBlur instead of seperable convolutions was giving similar results (almost equal) in terms of speed. I favored seperable convolutions over cv2.GuassianBlur because it was consistent with the design decision of creating kernels in a similar fashion to PIL. If you want any changes, please let me know.

@ternaus
Copy link
Collaborator

ternaus commented Feb 18, 2025

I checked. GaussianBlur and Separable give similar performance, with Gaussian being a bit faster.

But here we want normalized kernel to match PIL, which prevents from using Gaussian Directly and using separable here was a material 2.5 speedup.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants