VeniVici
VeniVici

Reputation: 45

How do you implement a calculated Gaussian kernel?

I am struggling with my ability to implement a calculated gaussian kernel to return a blurred image. My current code that calculates the kernel is below:

const int m = 5;
const int n = 5;
double sigma = std;
Mat Gauss;
double kernel[m][n];
for ( int x = 0; x < m; ++x )
    for ( int y = 0; y < n; ++y )
    {
        kernel[x][y] = (1 / (sigma * (sqrt(2 * M_PI))))
            * exp(-0.5 * (std::pow((x - avg) / sigma, 2.0)
                + pow((y - avg) / sigma, 2.0) ) / (2 * M_PI * sigma * sigma));
    }

However, I can't figure out how to apply this to the image in a way that I am returned a blurred image. I would appreciate it if anyone could give me some pointers in a way that I can apply this to an image.

I was thinking of using a for loop to replace the pixels of the original image but I could not properly implement this idea. Thank you for your time.

Upvotes: 1

Views: 1284

Answers (1)

Michael
Michael

Reputation: 5939

It sounds like you want to compute a convolution of the original image with a Gaussian kernel, something like this:

blurred[x][y] = Integral (kernel[s][t] * original[x-s][y-t]) ds dt

There are a number of techniques for that:

  1. Direct convolution: go through the grid and compute the above integral at each point. This works well for kernels with very small support, on the order of 5 grid points in each direction, but for kernels with larger support becomes too slow. For Gaussian kernels a rule of thumb for truncating support is about 3*sigma, so it's not unreasonable to do direct convolution with sigma under 2 grid points.

  2. Fast Fourier Transform (FFT). This works reasonable fast for any kernel. Therefore FFT became the standard way to compute convolution of nearly anything with nearly anything. Direct convolution beats FFT only for kernel with very small support.

  3. Analytical: integrals of some kernels have analytical expressions. In particular, integral of a Gaussian is the Erf function, and, at least on Unix systems, it's available as a function call. Moreover, on some hardware (such as GPUs) Erf is implemented in hardware. In some rare (but important) cases of coarse bi-level images one can replace convolution with Gaussian with a loop of Erf function calls.

For most computational system your best bet would be to go with FFT: it's fast and it's flexible enough to handle correctly any kernels and images.

Upvotes: 1

Related Questions