Original Post
🔒 Locked
Blur effect?
Advertisement
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 . .
. . . . .
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 . .
. . . . .
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 ;)
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]))); } } }
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 :)
. . 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 :)
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.
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.
Advertisement
