Gaussian Blur

Started by
3 comments, last by Drki 23 years, 8 months ago
Hy. I need some info how to do gaussian blur. Thanks.
Advertisement
In what context? If you want to do Gaussian blur in realtime it''s going to be rather tricky. If you''re looking to do a preprocess on textures, then... essentially, Gaussian blur is just a filtering operation on textures; it replaces each pixel with a weighted average of all the pixels within some distance of it (from a mathematical perspective the distance should be infinite but for practical considerations everyone clamps it to some range). The weight function is just a ''bell curve'' -- each pixel is weighted by e^-(d^2/d0^2), where d is the distance between the two pixels and d0 is a reference distance that says how wide your filter is (how much blur you get). Here''s some code off the top of my head, demonstrating how you''d do it on a greyscale image (i.e., one float per pixel, as opposed to 3 or 4 bytes):

    void GaussianBlur(float *RawBits, float *BlurredBits, float FilterWidth, int ImageWidth, int ImageHeight) {  int Clamp; // How far out we sample  int XLoop, YLoop, XInner, YInner;  float Dist, Weight;  float DataSum, WeightSum;  Clamp = (int) (3*FilterWidth); // This is a good heuristic  for (YLoop = 0; YLoop < ImageHeight; YLoop++) {  for (XLoop = 0; XLoop < ImageWidth; XLoop++) {    DataSum = WeightSum = 0.0f;    for (YInner = -Clamp; YInner <= Clamp; YInner++) {    for (XInner = -Clamp; XInner <= Clamp; XInner++) {      X = XLoop+XInner; Y = YLoop+YInner; // the pixel we sample      if ((X >= 0) && (X < ImageWidth)       && (Y >= 0) && (Y < ImageHeight)) {        // This pixel falls within the bounds of the image;        // add it to the weighted average        Dist = (float) (XInner*XInner+YInner*YInner);        Weight = fexp(Dist/(FilterWidth*FilterWidth));        DataSum += Weight*RawBits[Y*ImageWidth+X];        WeightSum += Weight;      }    }    }    if (WeightSum > 0.0f) {      BlurredBits[YLoop*ImageWidth+XLoop] = DataSum/WeightSum;    } else {      BlurredBits[YLoop*ImageWidth+XLoop] = 0;    }  }  }}    


Note that I _don''t_ recommend ever using the above code as is. It''s completely unoptimized, the most egregious sin probably being the fact that weights should be precomputed so you don''t have to make a couple dozen calls to fexp() per pixel. There are a number of other smaller optimizations that could stand to be done, too; hopefully this will at least give you the basic gist of things, though.
Thanks man, I''ll give it a try.
Actualy I need it to do a mip-map images, but I think this could be usefull.

Drki.

Actually, for MIPmaps you probably _don''t_ want Gaussian blur; all you really want is to scale down your initial texture image by averaging it; that is, each texel in the subsampled (half-size) image is simply the average of the four pixels in the original image that it covers. This is basically because trilinear sampling is a (rough) approximation to summed-area tables which traditionally use a box filter (all ones in the area that it covers), and so a box (i.e., averaging) filter is the appropriate one to use when subsampling.
I need to do this in my own application as well. Does anybody know a fast way to do this?

I was thinking of using GDI''s GetPixel for averaging, but that is really slow.

Should I instead lock the surface, and then get the pixelformat, and then do math to figure the byte in the surface? I''ve never directly manipulated a surface before (without using GDI).

Does anybody have a MIP map blur function already made that is fast?

This topic is closed to new replies.

Advertisement