Archived

This topic is now archived and is closed to further replies.

Gaussian Blur

This topic is 6348 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hy. I need some info how to do gaussian blur. Thanks.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites