Bilateral Filtering

Started by
46 comments, last by Tipotas688 13 years, 5 months ago
OK so I am trying to finish first my Gaussian Filter in order to proceed to the bilateral one:

float GaussianCoef(int x, int y){	float sigma = 1.0f;	return  ( 1 / ( sqrt(2*3.14f) * sigma ) ) * exp( -(x*x+y*y) / (2*sigma*sigma) );}float4 BilateralFiltering(VertexOut input) : COLOR0{	float4 k11 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(-0.01,-0.01))*GaussianCoef(2,2);	float4 k12 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(-0.01,0))*GaussianCoef(1,1);	float4 k13 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(-0.01,0.01))*GaussianCoef(2,2);		float4 k21 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0,-0.01))*GaussianCoef(1,1);	float4 k22 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0,0))*GaussianCoef(0,0);	float4 k23 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0,0.01))*GaussianCoef(1,1);		float4 k31 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0.01,-0.01))*GaussianCoef(2,2);	float4 k32 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0.01,0))*GaussianCoef(1,1);	float4 k33 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0.01,0.01))*GaussianCoef(2,2);}


All I get is the picture blurred but darker which makes sense considering with the value i am multiplying it with, I have got something wrong with the sigma (its supposed to be the size of the window, does it refer to the kernel?), also is my distance from the center pixel right if my kernel is 3x3? Kernel:
212
101
212
Advertisement
Just a tip:
Never ever blur over x and y in one pass. By blurring over the width and than over the height you don't need to sample any diagonals at all.
Also use a precomputed array for your coefficients. It will speed up the whole process. This might not really be possible since you want to use a bilateral filter, but keep it in mind.

Now to your question...

Sigma needs to be the blur kernels width / 3
if my kernel is:

-1,-1 -1,0 -1,1
0,-1 0,0 0,1
1,-1 1,0 1,1

then its distances should be:

sqrt(2) 1 sqrt(2)
1 0 1
sqrt(2) 1 sqrt(2)


so I should use floats for my Gaussian method shouldn't I?

for a 3x3 kernel the radius is 1 so the sigma is 0.33
The graphics card itself calculates with floats either way, so it's safer to use floats and like you said, you'll need them anyway.

You should also stay in the same space. Your samples are 0.01f away. So your blur kernel should be 0.01f wide, the values you calculate the coefficients with should be float2(+-0.01f, +-0.01f) and sigma should be 0.01f/3.
I am going to multiply both x and y for starters and then I ll try to do it in 2 passes.

Using this makes the result brighter:
float GaussianCoef(float x, float y){	float sigma = 0.01f/3;	return  ( 1 / ( sqrt(2*3.14f) * sigma ) ) * exp( -(x*x+y*y) / (2*sigma*sigma) );}float4 BilateralFiltering(VertexOut input) : COLOR0{	float4 color = float4(0,0,0,0);			const float pixel = 0.01f;	float sqrtTwoPixel = sqrt(2)*pixel;		float4 k11 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(-pixel,-pixel))*GaussianCoef(sqrtTwoPixel,sqrtTwoPixel);	float4 k12 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(-pixel,0))*GaussianCoef(pixel,pixel);	float4 k13 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(-pixel,pixel))*GaussianCoef(sqrtTwoPixel,sqrtTwoPixel);		float4 k21 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0,-pixel))*GaussianCoef(pixel,pixel);	float4 k22 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0,0))*GaussianCoef(0,0);	float4 k23 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0,pixel))*GaussianCoef(pixel,pixel);		float4 k31 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(pixel,-pixel))*GaussianCoef(sqrtTwoPixel,sqrtTwoPixel);	float4 k32 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(pixel,0))*GaussianCoef(pixel,pixel);	float4 k33 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(pixel,pixel))*GaussianCoef(sqrtTwoPixel,sqrtTwoPixel);	color =  (k11+k12+k13+k21+k22+k23+k31+k32+k33);	return color/9;   //color / sum;}
GaussianCoef(pixel, pixel);
Or
GaussianCoef(0, pixel);
Or
GaussianCoef(pixel, 0);
Or
GaussianCoef(0, 0);

Always. sqrt(2)*pixel is wrong.
so like:
	float4 k11 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(-pixel,-pixel))*GaussianCoef(pixel,pixel);	float4 k12 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(-pixel,0))*GaussianCoef(pixel,0);	float4 k13 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(-pixel,pixel))*GaussianCoef(pixel,pixel);		float4 k21 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0,-pixel))*GaussianCoef(0,pixel);	float4 k22 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0,0))*GaussianCoef(0,0);	float4 k23 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(0,pixel))*GaussianCoef(0,pixel);		float4 k31 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(pixel,-pixel))*GaussianCoef(pixel,pixel);	float4 k32 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(pixel,0))*GaussianCoef(pixel,0);	float4 k33 = tex2D( ColoredTextureSampler, input.textureCoordinates.xy + float2(pixel,pixel))*GaussianCoef(pixel,pixel);

The result always is:
PhotobucketPhotobucket

[Edited by - Tipotas688 on November 11, 2010 1:25:52 PM]
Your gaussian blur filter isn't even correct. You mixed the one dimensional formula with the two dimensional. There's no square root in the two dimensional one and it's pow(sigma, 2).

return ( 1 / ( 2*3.14f*sigma*sigma ) ) * exp( -(x*x+y*y) / (2*sigma*sigma) );
ah you are right, i forgot to change it but now its even brighter

Photobucket
No play a bit around with the values you use. Use "1" instead of "pixel", or sigma = 0.33; since I start to doubt what I said.
I always work in "pixel" space where I only have values ranging from 1 to 5 (for the gaussian blur). And not 0.01f.

This topic is closed to new replies.

Advertisement