# Gaussian Blur Filter C++

I got asked to make some new blur filters.

The available convolution filters turned out to be rather slow and a set of new ones was requested. Getting to know the specific PDK (plugin development kit) was tricky, writing the plug-ins on the other end was a lot of fun. Below there is a snippet of code on how to write a Gaussian and Box blur kernel in C++.

Note that the height field input parameter (HField *inHeightMap and BuildContext &inContext)   can be replaced with any other (pixel) matrix using for example Devil or FreeImage.

The BuildContext is used to generate a second image and is used as a temporary pixel placeholder.

Now for the code:

I’ll start by defining the Gaussian Kernel. When called this kernel function returns an array of floats that define the actual per pixel scalar values.

// Calculates a 1d gaussian bell shaped kernel
float* GBlur::ComputeGaussianKernel(const int inRadius, const float inWeight)
{
int mem_amount = (inRadius*2)+1;
float* gaussian_kernel = (float*)malloc(mem_amount*sizeof(float));

float twoRadiusSquaredRecip = 1.0 / (2.0 * inRadius * inRadius);
float sqrtTwoPiTimesRadiusRecip = 1.0 / (sqrt(2.0 * PI) * inRadius);
float radiusModifier = inWeight;

// Create Gaussian Kernel
int r = -inRadius;
float sum = 0.0f;
for (int i = 0; i < mem_amount; i++)
{
float x = r * radiusModifier;
x *= x;
float v = sqrtTwoPiTimesRadiusRecip * exp(-x * twoRadiusSquaredRecip);
gaussian_kernel[i] = v;

sum+=v;
r++;
}

// Normalize distribution
float div = sum;
for (int i = 0; i < mem_amount; i++)
gaussian_kernel[i] /= div;

return gaussian_kernel;
}

Now this kernel can be used to blur an image. The image comes in as a an array of floats.
This array represents a greyscale image. A colored image would have the RGB(A) components blurred.

// Calculates the Gaussian Blur and stores the result on the height map given
void GBlur::GaussianBlur(HFPointer inHeightMap, const int inRadius, BuildContext &inContext, const float inWeight)
{
int pixels_on_row = 1+(inRadius*2);
int height = inHeightMap->h();
int width = inHeightMap->w();

HFPointer temp_smap   = GetNewHF(inContext);    ///< Temporary map used for storing intermediate results
temp_smap->Clear();

float* gaussian_kernel = ComputeGaussianKernel(inRadius,inWeight); ///< Compute our gaussian 1d kernel

float* pheight_map = inHeightMap->GetDataPtr();             ///< Pointer to current map
float* ptemp_map = temp_smap->GetDataPtr();                 ///< Pointer to intermediate map

int current = 0;                                            ///< Helps keep track of where we are

// Do a one dimensional blur in the y direction
// We use the temp map to find the horizontally blurred pixels
// These are then used to compute a first blur pass and stored in the original map
float* out = ptemp_map;
int height_clamp = height - 1;
int width_clamp = width - 1;

for(int y=0;y<height; y++)
{
int row = y*width;              ///< Specifies the current row

for(int x=0;x<width; x++)
{
float blurred_value = 0.0f;
for(int xoffset = 0; xoffset < pixels_on_row; xoffset++)
{
// Clamp x index
int sx = iClamp(0,width_clamp,(x-inRadius)+xoffset);

// Calculate newly blurred value
blurred_value += pheight_map[row+sx]*gaussian_kernel[xoffset];
}

// Set our calculated value to our temp map
*out++ = blurred_value;

// Increment where we are
current++;
}

inContext.ReportDeviceProgress(this, y/2 ,inHeightMap->h());
}

// Used for showing progress
int half_height(inHeightMap->h() / 2);

// Do a one dimensional blur in the x direction
// We use the temp map to find the horizontally blurred pixels
// These are then used to compute a second blur pass and stored in the original map
out = pheight_map;
for(int y=0;y<height; y++)
{
for(int x=0;x<width; x++)
{
float blurred_value = 0.0f;
for(int yoffset = 0; yoffset < pixels_on_row; yoffset++)
{
// Clamp our offset in y
int sy = iClamp(0,height_clamp,(y-inRadius)+yoffset);

// Calculate blurred value
blurred_value += (ptemp_map[(sy * width) + x]*gaussian_kernel[yoffset]);
}

// Set the original height map value to our computed value
// This is the actual blurred value (previously scaled)
*out++ = blurred_value;

// increment counter and report progress to wm
current++;
inContext.ReportDeviceProgress(this,current/2,inHeightMap->area());
}

inContext.ReportDeviceProgress(this, half_height + (y/2),inHeightMap->h());
}

// Release
free(gaussian_kernel);
gaussian_kernel=NULL;
temp_smap->Clear();
temp_smap->releaseAccessible();
}

## 12 thoughts on “Gaussian Blur Filter C++”

1. The html formatting messed up the for loops in Blur::GaussianBlur()

• Thanks for pointing it out, fixed!

2. When someone writes an article he/she keeps the thought of a
user in his/her brain that how a user can know it.
So that’s why this post is outstdanding. Thanks!

3. Hey,
thanks for this nice post. I’m not sure if I’m missing something, but I miss “float*” in front of “gaussian_kernel” in the 5th line of your code. Sorry if I oversee something.
Cheers, Alexey

• Hi There,

I used this function inside a plugin and declared gaussian_kernel as a member. In the example this is indeed a pointer 🙂

4. hi,
Nice code here but i don’t understand why this
float v = sqrtTwoPiTimesRadiusRecip * exp(-x * sqrtTwoPiTimesRadiusRecip);

shouldn’t it be
float v = sqrtTwoPiTimesRadiusRecip * exp(-x * twoRadiusSquaredRecip);

• I think you’re absolutely right, typo there. Changed, thanks!

5. Good content, I truly wait for fresh news by you.

6. Good day site operator, thnxx for putting up this post. I found it superb. Truly, Scarlett..

7. I don’t even know the way I ended up the following, but I thought this article was superb. I have no idea who you could be but clearly you?¯re likely to a celebrated blogger if you aren?¯t previously Cheers!

8. hi blogger, I found your website from altavista and browse just a few within your other website posts.These are pleasant. Pleasee hold them coming. Have a great day, Thomas Everyday.

9. You had some really good concepts there. I created a lookup on the situation and detected most peoples will concur along with your blogging site.