Gaussian blurring is achieved by recalculating the value of each pixel by multiplying out some factor of its neighbours. This is called
convolving the image with a
filter. The weights which you apply to the neighbours are determined according to the Gaussian (aka Normal) distribution.
Horrible, hard to understand literature:
http://en.wikipedia.org/wiki/Gaussian_blurBasically, you loop through each pixel in the image you want to blur and then write the output to a new image. Here's a code sample:
Code:
//2 4 5 4 2
//4 9 12 9 4 1
//5 12 15 12 5 x ---
//4 9 12 9 4 159
//2 4 5 4 2
int getIntensity(int x, int y){
if (x<0 || y<0 || x>=width || y>=height) return 0;
return imageData[y][x];
}
void blur(){
std::vector< std::vector<int> > imageDataTemp = imageData;
short kernel[5][5] = { {2,4,5,4,2}, {4,9,12,9,4}, {5,12,15,12,5}, {4,9,12,9,4}, {2,4,5,4,2} };
for (int x=0; x<width; x++){
for (int y=0; y<height; y++){
double result=0.0;
for (int ky=-2; ky <= 2; ky++){
for (int kx=-2; kx <= 2; kx++){
result = result + getIntensity(x+kx,y+ky)*kernel[kx+2][ky+2];
}
}
result /= 159;
if (result>255) result=255;
imageDataTemp[y][x] = static_cast<int>(result);
}
}
imageData = imageDataTemp;
}
My getIntensity function is returning a pixel value in the image, but when a pixel is requested from beyond the bounds of the image, then it only returns 0. In truth this is less than desirable in the usual case, as it's making up data that will skew the results of the blur on the edges of the image. A better solution would be to use more complicated logic to return the mirror pixel from the edge. I.e. if pixel (-1,-19) is requested, return pixel (1,19) from the real image.