Skip to main content
GameDev.net gamedev.net
🔒 Locked

How to write Gaussian blur filter in C++ tool

Started by yahk Mar 16, 2005 at 9:29 PM 10 replies 46.9k views
Original Post
yahk
yahk
please help me! i want to write the Gaussian filter code, but i do not how to write.i want to see the source code in c++ you can send to me my Email is must1001@163.com If you have any ideas or a good site with file format listing, please let me know.
Grizwald
Grizwald
Forgive me if I misunderstand, but a guassian blur is just a weighted average of the pixels in an image.


Ok, this is REALLY oversimplified, but take pixel (x,y) as our source pixel. Our blur function (although not really guassian) would be



blur(x,y) = src_img(x,y) + w*src_img(x-1,y-1) + w*src_img (x,y-1) ...

wow that sucks, i'm tired

Basically you take a weighted average of the pixel and its neighboring pixel, and the weights come from the guassian function, which looks like a bell

Img from mathworld.com. ignore the image on the right

look up normal distribution, guassian curves and other information.

and for file formits, check out wotsit
I love me and you love you.
yahk
yahk
Thanks for your help!

but as you write. i can not understand at all!
because :

Gaussian Filter

It is sometimes useful to apply a Gaussian smoothing filter to an image before performing edge detection. The filter can be used to soften edges, and to filter out spurious points (noise) in an image.


By using a small Gaussian filter (of the order – 3 x 3 matrix) and then applying an edge detector, you will see a great deal of fine detail. However, there will also be a lot of unwanted edge fragments appearing due to noise and fine texture.


For a larger smoothing filter (of order – 31 x 31) there will be fewer unwanted edge fragments, but much of the detail in the edges will also be lost.



3x3 Gaussian mask:




do you have Gassian filter C++ source code for me?

yahk
yahk
those code for Gaussian filter.
i write it before

please help me to check it!


void ImageType::Gaussian_filter( void )
{

//*/
int i,j;
int mask[3][3]={{1,2,1},{2,4,2},{1,2,1}};
//int sum,sum1,sum2,sum3,sum4,sum5,sum6,sum7,sum8,cnt=0;
Byte *arry_1,*arry_2;


arry_1 = (Byte *) malloc(x_size * y_size * 3 * sizeof(Byte));
arry_2 = (Byte *) malloc(x_size * y_size * 3 * sizeof(Byte));

for( i=0; i {
for( j=0; j {
int sum=0,sum1=0,sum2=0,sum3=0,sum4=0;
int sum5=0,sum6=0,sum7=0,sum8=0;
int cnt[3]={0};
for(int rgb=0;rgb {

sum1=pixels[((i-1)*y_size+j-1)*3+rgb];
sum2=pixels[((i-1)*y_size+j)*3+rgb];
sum3=pixels[((i-1)*y_size+j+1)*3+rgb];
sum4=pixels[(i*y_size+j-1)*3+rgb];

sum=pixels[(i*y_size+j)*3+rgb];

sum5=pixels[(i*y_size+j+1)*3+rgb];
sum6=pixels[((i+1)*y_size+j-1)*3+rgb];
sum7=pixels[((i+1)*y_size+j)*3+rgb];
sum8=pixels[((i+1)*y_size+j+1)*3+rgb];


if( j<1 && i<1 )
{
cnt[rgb]=sum*mask[1][1] + sum5*mask[1][2] + sum7*mask[2][1] +sum8*mask[2][2];

}
else if( j>x_size-2 && i<1 )
{
cnt[rgb]=sum*mask[1][1] + sum4*mask[1][0] + sum6*mask[2][0] + sum7*mask[2][1];

}
else if( (j>0 && i<1) || (j {
cnt[rgb]=sum*mask[1][1] + sum4*mask[1][0] + sum6*mask[2][0] + sum7*mask[2][1] +
sum5*mask[1][2] + sum8*mask[2][2];
}
else if( (i>0 && j<1) || (i {
cnt[rgb]=sum*mask[1][1] + sum2*mask[0][1] + sum3*mask[0][2] + sum5*mask[1][2] +
sum7*mask[2][1] +sum8*mask[2][2];
}
else if( i>y_size-2 && j<1)
{
cnt[rgb]=sum*mask[1][1] + sum2*mask[0][1] + sum3*mask[0][2] + sum5*mask[1][2];
}
else if( (j>0 && i {
cnt[rgb]=sum*mask[1][1] + sum2*mask[0][1] + sum3*mask[0][2] + sum4*mask[1][0] +
sum5*mask[1][2];
}

else if(i {
cnt[rgb]=sum*mask[1][1] + sum2*mask[0][1] + sum4*mask[1][0] + sum1*mask[0][0];
}

else if( (i>0 && j {
cnt[rgb]=sum*mask[1][1] + sum2*mask[0][1] + sum4*mask[1][0] + sum6*mask[2][0] +
sum7*mask[2][1];
}
else
{
cnt[rgb]=sum*mask[1][1] + sum1*mask[0][0] + sum2*mask[0][1] + sum3*mask[0][2] +
sum4*mask[1][0] + sum5*mask[1][2] + sum6*mask[2][0] + sum7*mask[2][1] +
sum8*mask[2][2];

}

arry_1[rgb]=cnt[rgb]/16;
//arry_2[(i*y_size+j)*3+rgb]=arry_1[rgb];
}
arry_2[(i*y_size+j)*3]=0xff0000 | (arry_1[0]) | (arry_1[1])<<8 | (arry_1[2])<<16;


}
}


for( i=0; i < x_size*y_size*3; i++)
{

pixels = arry_2;



}

free(arry_1);
free(arry_2);
PinkyAndThaBrain
PinkyAndThaBrain
Quote:
Original post by yahk
By using a small Gaussian filter (of the order – 3 x 3 matrix)

Just to clarify, this is talking about a truncated gaussian, the gaussian function mentioned previously is sampled and truncated to give for instance a 3x3 matrix ... gaussian filters cannot just be described hy their size, but they also need to specify their standard deviation.
Steadtler
Steadtler
Here is some old code of mine. Welcome to the wonderful world of image processing:

bool CreateGaussianFilter(double piSigma, double piAlpha, Image &poFilter){	long lSize = ((int)(piAlpha * piSigma) / 2)*2  + 1; //force odd-size filters        long lHalfSize = lSize / 2;	poFilter.ResetImage(lSize, lSize);		for (int x = 0; x < lSize; x++)	{		long FakeX = x - lHalfSize;		for (int y = 0 ; y < lSize ; y++)		{			long FakeY = y - lHalfSize			double k = 1.0 / (2.0 * PI * piSigma * piSigma);			poFilter.SetPixel(x, y, k * exp( (-1 * ((FakeX * FakeX) + (FakeY *FakeY))) / (2 * piSigma * piSigma)));		}		}	return true;}


Its pretty simple. You just center your filter (thats the "FakeX" and "FakeY" and plug them into the gaussian equation. Sigma is the standard deviation. Alpha controls the size (thus precision) of the filter. k is the normalization factor.

Have fun!
yahk
yahk
Tkank for all!

:)
Steadtler
Steadtler
by the way:

Quote:
It is sometimes useful to apply a Gaussian smoothing filter to an image before performing edge detection. The filter can be used to soften edges, and to filter out spurious points (noise) in an image.



Actually, you can have the same effect by using the first order derivatives of the gaussian as your edge detection filters. Thats called a Canny edge detector. (and his thesis is quite fun to read too).

raydog
raydog
I remember seeing a lot of Gaussian blur code in these forums somewhere.

I mostly interested in seeing something that works exactly like Photoshop's
Gaussian blur. Input is just a floating-point radius in terms of pixels.
JimPrice
JimPrice
OK - so I know nothing about this topic, but quick question:

This looks like a simple example of what's known in statistics as Kernel Smoothing; a kernel function just being a function that's symmetric, integrates to 1 and is unimodal.

So: question - are other kernel smoothers used? The gaussian has some nice characteristics - nice continuity properties for example - but has what I would have thought are some undesirable properties - such as having the reals as it's domain, and a moderately complex (read : lots of calculations required) density function. I assume these can be addressed by truncation (although this would require adjusting the pdf for a true kernel smoother - but I'm not sure this is an issue for the presented scenarios) and precalculation of smoothing-elements (which you could only do on something with known spacing-characteristics i.e. a grid of pixels) respectively.

So : any other reasons for using gaussian smoothers? Are other alternatives used? If not, any particular reason?

Thanks in advance,
Jim.
DrakeSlayer
DrakeSlayer
here is my code for the gaussian filter.
the gaussian kernel is separable.it means you can apply the filter in two passes,
for an increased speed.

for a kernel size of n, the complexity is O(n) instead of O(n*n).



void Image::gaussianBlur(float radius){	//nombre d'octets par pixel	int bp=mBpp/8;	unsigned char* temp=new unsigned char[mWidth*mHeight*bp];	float sigma2=radius*radius;	int size=5;//good approximation of filter	float pixel[4];	float sum;		//blurs x components	for(int y=0;y<mHeight;y++)	{		for(int x=0;x<mWidth;x++)		{			//process a pixel			sum=0;			pixel[0]=0;			pixel[1]=0;			pixel[2]=0;			pixel[3]=0;			//accumulate colors			for(int i=max(0,x-size);i<=min(mWidth-1,x+size);i++)			{				float factor=exp(-(i-x)*(i-x)/(2*sigma2));				sum+=factor;				for(int c=0;c<bp;c++)				{					pixel[c]+=factor*mData[(i+y*mWidth)*bp+c];				};			};			//copy a pixel			for(int c=0;c<bp;c++)			{				temp[(x+y*mWidth)*bp+c]=pixel[c]/sum;			};		};	};	//blurs x components	for(int y=0;y<mHeight;y++)	{		for(int x=0;x<mWidth;x++)		{			//process a pixel			sum=0;			pixel[0]=0;			pixel[1]=0;			pixel[2]=0;			pixel[3]=0;			//accumulate colors			for(int i=max(0,y-size);i<=min(mHeight-1,y+size);i++)			{				float factor=exp(-(i-y)*(i-y)/(2*sigma2));				sum+=factor;				for(int c=0;c<bp;c++)				{					pixel[c]+=factor*temp[(x+i*mWidth)*bp+c];				};			};			//copy a pixel			for(int c=0;c<bp;c++)			{				mData[(x+y*mWidth)*bp+c]=pixel[c]/sum;			};		};	};	delete[] temp;};








Steadtler
Steadtler
@Raydog: That means they have a fixed precision (alpha), and instead of specifying the standard deviation (sigma), you specify the filter size.

@JimPrice: The gaussian have a lot of useful and well-understood mathematical properties that are useful in image processing. Also, most of the time noise is considered as being additive and normally distributed. Finally, the gaussian is a well-shaped low-pass filter in the frequency domain. Other common alternatives are perfect low-pass filters, mean filters, IIR filters.

@DrakeSlayer: yep, separable filters rocks!

Topic Locked

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

Sign in to reply to this topic.