Merged
Conversation
joeyballentine
approved these changes
Jul 24, 2023
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This implements my idea for a fast Gaussian blur. I basically just downscale the image, blur the downscaled image, and then upscale it again with fast linear interpolation. The downscaling factor depends on the radius of the blur, and is chosen in a way that keeps the maximum error below 0.1%. So the fast blur is guaranteed to have no visible difference even with 10bit color.
The speedup we get depends on the radius. Fast blur can't downscale a lot for small radii to keep error guarantees. In fact, we don't downscale at all until r=11, so there is no speedup at all before that.
Measurements
I tested this on a 2117x1080 RGB image.
It's also interesting to note that fast blur gets faster between r=11 and r=25. This is not a measuring error. Larger radii allow for more downscaling, which speeds things up. However, due to OpenCV's
resizeimplementation, we need to do a small post blur to get rid of artifacts. The more we downscale, the worse these artifacts get, and the larger we need to make the post blur. So a large downscale factor can counter-intuitively result in a slower overall blur. This post blur is the main reason why fast blur gets slower for large radii.The artifacts look like this btw (r=100, here amplified 8100x):


And this is what the post blur does to them:
So the post blur nicely fixes these artifacts.
The post blur actually accounts for 40% to 66% of the total time fast blur takes. So fast blur can potentially be 2-3x faster, but we would have to live with spikes. Honestly, OpenCV should just fix their linear interpolation...
Different radii
Since fast blur supports different radii for x and y, I had to press them into this downscaling framework somehow. Unfortunately, resizing x and y with different scaling factors makes the maximum error very difficult to predict.
So I gave up on this. Instead, I simply choose the less scaling factor of x and y. This means that fast blur is just as slow are regular Gaussian for combinations where either x or y are below 11. E.g. rxy=(10, 100) takes 2.3 seconds with both. But (20, 100) only takes 0.14s with fast blur. Luckily, very different blur radii aren't commonly used.