Skip to main content
gamedev.net
🔒 Locked

Blur effect?

Started by gcsaba2 6 replies 1.8k views
Original Post
gcsaba2
gcsaba2
Can someone provide me with an algorithm (or link to a document) on how to blur 2D images? I was thinking about Gaussian blur, but any other simple blurring would be okay. Thanks ;)
RandomAxess
RandomAxess
for a 2d image, the algorithm is as follows:
for each texture element in A, find the 4 neighbors.
Average the RGB values of the 5 elements.
Read this into another texture in the exact same cell in B.
Thus, you create a "blurred" image based off the original. You can then copy over the original if you want.
So in a bad picture:

Texel in Texture A (Hightlighted by A):
. . . . .
. . A . .
. . . . .
Neighbors for texel A, and the texel (highlighted by X) :
. . X . .
. X A X .
. . X . .

Average the 5 texel RGB values, keep the alpha value the same, read into Texture B:
. . . . .
. . X . .
. . . . .

gcsaba2
gcsaba2
I've coded the algorithm and it works, thanks! :)

The problem is this works a bit too slow. My framerate dropped from 40 to 3 by simply applying the blur effect to a picture in each frame. I don't really mind this, cause I wouldn't want to do this very often, but the problem is, if I want to archieve a greater degree of blurness, I have to call the blur() function like 20 times. Is there a better way to get to this level from just one pass through the bitmap?

Btw. this is my code. Nothing special, it's just RandomAxess's algorithm put into C ;)

inline int Avg(int nums[], int n){    int sum = 0;    for (int i=0; i<n; i++)      sum += nums;    return sum / n;}    inline void Blur(BITMAP* Src, BITMAP* Dest){        int r[5];    int g[5];    int b[5];    int iPixel[5];    for (int y=1; y<Src->h-1; y++)    {        for (int x=1; x<Src->w-1; x++)        {            iPixel[0] = getpixel(Src,x,y);            iPixel[1] = getpixel(Src,x-1,y);            iPixel[2] = getpixel(Src,x+1,y);            iPixel[3] = getpixel(Src,x,y-1);            iPixel[4] = getpixel(Src,x,y+1);            for (int i=0; i<5; i++)            {                r = getr(iPixel);                g = getg(iPixel);                b = getb(iPixel);                            }                r[0] = Avg(r,5);            g[0] = Avg(g,5);            b[0] = Avg(b,5);            putpixel(Dest,x,y,makeacol(r[0],g[0],b[0],geta(iPixel[0])));        }        }    } 
DekuTree64
DekuTree64
Looks pretty good to me. One way you can speed up such an algorithm is to recycle the middle row. Your pattern looks like this:

. . 1 . .
. 2 3 4 .
. . 5 . .

and when you move 1 pixel to the right, pixels 3 and 4 are still going to be involved in the average. If you add up 2, 3 and 4 and store those RGB values in some temporary variables before you add in pixels 1 and 5, then next time through the loop you can take that 2,3,4 sum and subtract 2's value from it so you're just left with the sum of 3 and 4. Then add in the new pixel (the one to the right of 4), and store back to the temporary vars before adding in the next above/below pixels.
The main improvement is that you don't have to separate out the R/G/B values of those pixels every time.

To do a blurrier blur in one pass, just take more pixels into account. Maybe make a pattern like:

. . X . .
. X X X .
X X X X X
. X X X .
. . X . .

so you're averaging 13 pixels instead of just 5. Then the recycling optimization will really make a difference, because you still only have to subtract the left edge pixels and add in the right edge, instead of separating and adding up all those middle pixels.

Still, you could just do brute force with the 13 pixel pattern and it would probably be faster than running the 5 pixel one several times. Only attempt the optimized version if you enjoy such torment :)
MikeyO
MikeyO
You could always just lower the resolution & stretch:D
Virum
Virum
Quote:
Original post by MikeyO
You could always just lower the resolution & stretch:D


Ummm, no:



HUGE quality difference, as you can see. The "pixelation blur" also has distortions.

Basically, downsampling and then upsampling to get an effect like a blur isn't a good idea.

Cheers!

-Virum
--------------------------------It's time to prove to your friends that your worth a damn. Sometimes that means dying; sometimes that means killing a whole lotta people.
Ademan555
Ademan555
For the record... you may want to consider doing this in a fragment shader. (render to texture then apply blur using the algo you used except using tex coords rather than indices to access pixels)

hope that helps
-Dan
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out hi
noisecrime
noisecrime
To start to learn about blurs, you could do worse than check this site out.
3 blur tutorials

Read each blur tutorial in turn, you'll see how things can be sped up.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.