Recent

Author Topic: Fast hardware image blur  (Read 30604 times)

simin_sh

  • Full Member
  • ***
  • Posts: 143
Re: Fast hardware image blur
« Reply #45 on: March 09, 2017, 10:58:39 am »
I have a question about the algorithm of blur.

When I ping pong between buffers, it seems that something is wrong about the blur functionality, because with the various number of ping pong between buffers and having a deeper blur, the progress of blur is not what it should be, I mean the blur picture in 25 times blur is not that different from 35 times blur!

And you can see from the picture attached what I mean exactly, upper left picture is blur 5 time, upper right is 30 times, and downer left is 60 times and down right is 300 times!

Any idea or suggestions??

Any help appreciated prior
Regards
OS Windows 10 - Lazarus 1.7 - FPC 3.1.1

circular

  • Hero Member
  • *****
  • Posts: 3070
    • Personal webpage
Re: Fast hardware image blur
« Reply #46 on: March 09, 2017, 08:17:19 pm »
That's normal. Repeating a blur does not make it much wider. The loop of the blur needs to take a wider range of pixels. And the weights need to be computed, for example in the shader.
Conscience is the debugger of the mind

simin_sh

  • Full Member
  • ***
  • Posts: 143
Re: Fast hardware image blur
« Reply #47 on: March 09, 2017, 08:34:41 pm »
Thank you for your replay
Because of that I am not completely sure about the algorithm I can not say how to implement such thing, I thought I just can do it with the ping pong between buffers, any Idea of how to increase the range of pixels?? Can I do this with increasing the weights for example??

Regards
OS Windows 10 - Lazarus 1.7 - FPC 3.1.1

circular

  • Hero Member
  • *****
  • Posts: 3070
    • Personal webpage
Re: Fast hardware image blur
« Reply #48 on: March 10, 2017, 07:24:32 pm »
You can use Gauss formula:
https://en.wikipedia.org/wiki/Gaussian_blur

There are sqrt and exp functions in GLSL.

The actual radius is roughly twice the sigma value. So for a sigma value of 5, you would loop from -10 to 10, or as in the algorithm you've used, sum the value at x+0 and then loop from 1 to 10 (including x-1 and x+1, then x-2 and x+2, etc.).

To be sure to have a correct sum, you also need to sum the weights, so that in the end you can divide by it. Otherwise you won't be sure that the sum of the weights is equal to 1. Instead it will be something like 0.99, so colors would get slightly darker.

Does it make sense?



Conscience is the debugger of the mind

simin_sh

  • Full Member
  • ***
  • Posts: 143
Re: Fast hardware image blur
« Reply #49 on: March 11, 2017, 08:32:09 am »
Thank you for your replay.

But no I can not understand the changes you described for having a deeper blur, or a blur with custom Radius, can you give me a sample code of what you mean please?

And I am not that much familiar with GLSL, But I am learning about it.

Any help appreciated prior
Regards
OS Windows 10 - Lazarus 1.7 - FPC 3.1.1

circular

  • Hero Member
  • *****
  • Posts: 3070
    • Personal webpage
Re: Fast hardware image blur
« Reply #50 on: March 11, 2017, 10:47:34 am »
I am also learning GLSL my friend. However I will give you a hand.

The horizontal shader would something like:
Code: glSlang  [Select]
  1. uniform sampler2D image;
  2. uniform ivec2 textureSize;
  3. varying vec2 texCoord;
  4.  
  5. out vec4 FragmentColor;
  6.  
  7. #define PI 3.14159265358979323846
  8.  
  9. //compute gauss function for sigma and x
  10.  
  11. float gauss(float sigma, float x)
  12. {
  13.         float normalized = x/sigma;
  14.         return 1/(sqrt(2*PI)*sigma)*exp(-0.5*normalized*normalized);
  15. }
  16.  
  17. void main(void)
  18. {
  19.         float sigma = 10;
  20.         //the range of pixels for which the weight will be at least 1% is roughly 2*sigma
  21.         int range = int(2*sigma+0.5);
  22.        
  23.         float weight = gauss(sigma, 0);
  24.         float totalWeight = weight;
  25.         FragmentColor = texture2D( image, texCoord/textureSize ) * weight;
  26.        
  27.         for (int i=1; i<=range; i++) {
  28.                 weight = gauss(sigma, i);
  29.                 FragmentColor += texture2D( image, (texCoord + vec2(i, 0.0))/textureSize ) * weight;
  30.                 FragmentColor += texture2D( image, (texCoord - vec2(i, 0.0))/textureSize ) * weight;
  31.                 totalWeight += 2*weight;
  32.         }
  33.        
  34.         //normalize result because totalWeight is not exactly 1
  35.         FragmentColor /= totalWeight;
  36. }

I let you add "sigma" as a uniform parameter for the shader so that you can change it from the Pascal code.
Conscience is the debugger of the mind

simin_sh

  • Full Member
  • ***
  • Posts: 143
Re: Fast hardware image blur
« Reply #51 on: March 11, 2017, 12:58:49 pm »
Yes, thank you so much Circular, it looks like exactly what it should be, comparing with the blur deep in LazPaint.

Now I should know where is the problem with the size of picture and texture and displaying the result in the openglcontrol, and also check the time, because it takes 30ms for a picture of size 900*600 (regardless of sigma value) and its too much different from what it should be!

Regards
« Last Edit: March 11, 2017, 01:05:15 pm by simin_sh »
OS Windows 10 - Lazarus 1.7 - FPC 3.1.1

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Fast hardware image blur
« Reply #52 on: March 11, 2017, 03:02:32 pm »
it takes 30ms for a picture of size 900*600 (regardless of sigma value) and its too much different from what it should be!
Try to precalculate sqrt(2*PI) to a single float value. Calculator says it's 2.506628274631000502415765284811 ... Leave a few digits out for it to accept.

circular

  • Hero Member
  • *****
  • Posts: 3070
    • Personal webpage
Re: Fast hardware image blur
« Reply #53 on: March 11, 2017, 09:35:43 pm »
You can also try with a constant weight to see if it is faster.
Conscience is the debugger of the mind

lainz

  • Hero Member
  • *****
  • Posts: 3380
    • Lainz
Re: Fast hardware image blur
« Reply #54 on: March 11, 2017, 09:55:44 pm »
simin_sh You will release it? It will be nice to have opengl blur in bgrabitmap, I just need it to use in a project for the graphics contest, just for fun.

simin_sh

  • Full Member
  • ***
  • Posts: 143
Re: Fast hardware image blur
« Reply #55 on: March 12, 2017, 07:23:49 am »
it takes 30ms for a picture of size 900*600 (regardless of sigma value) and its too much different from what it should be!
Try to precalculate sqrt(2*PI) to a single float value. Calculator says it's 2.506628274631000502415765284811 ... Leave a few digits out for it to accept.


Thank you for your replay

Yes it made it faster, for the same sample it takes 50% less time. But I am not sure about the time I am calculating, because it takes different values in different run times! Once it takes 15ms, once it takes 16ms and once it takes 0! I will test it better and with different samples and see the difference.

Regards
« Last Edit: March 12, 2017, 07:28:06 am by simin_sh »
OS Windows 10 - Lazarus 1.7 - FPC 3.1.1

simin_sh

  • Full Member
  • ***
  • Posts: 143
Re: Fast hardware image blur
« Reply #56 on: March 12, 2017, 07:27:42 am »
You can also try with a constant weight to see if it is faster.


Thank you for your replay
You mean I can have weights calculated in an array for example and just use them??

Regards
« Last Edit: March 12, 2017, 07:36:15 am by simin_sh »
OS Windows 10 - Lazarus 1.7 - FPC 3.1.1

simin_sh

  • Full Member
  • ***
  • Posts: 143
Re: Fast hardware image blur
« Reply #57 on: March 12, 2017, 07:31:27 am »
simin_sh You will release it? It will be nice to have opengl blur in bgrabitmap, I just need it to use in a project for the graphics contest, just for fun.


I am still testing some things, but here is my final test project if it would be useful for you. You just need to have a Src.jpg file in Pic folder, because code will use it for blur.

Regards
OS Windows 10 - Lazarus 1.7 - FPC 3.1.1

circular

  • Hero Member
  • *****
  • Posts: 3070
    • Personal webpage
Re: Fast hardware image blur
« Reply #58 on: March 12, 2017, 11:57:17 am »
@simin_sh: What I am suggesting is to use weight = 1/(2*range+1)

That would give a box blur as a result.

Otherwise you can try to create the framebuffers only once, or recreate them only if the size has changed. And free them when the form is closed.

About the time begin 0 or 15 ms, that's normal because the grain of time is equal to 15 ms. To have more precision, you could use EpikTimer, or do the same thing 10 times and then divide the time by 10.
Conscience is the debugger of the mind

lainz

  • Hero Member
  • *****
  • Posts: 3380
    • Lainz
Re: Fast hardware image blur
« Reply #59 on: March 12, 2017, 02:02:32 pm »
Thanks you both for all this.

@Circular, you will include a blur demo in bgrabitmap or maybe somewhere in another repository?