1

I am trying to implement the Gaussian Filter in C. My output layout keeps coming out wrong, I tried playing with the rows and columns in my for loops but it didn't work. The output layout should look like this:

0.0161464   0.0294206   0.0359344   0.0294206   0.0161464   
0.0294206   0.0536078   0.0654768   0.0536078   0.0294206   
0.0359344   0.0654768   0.0799735   0.0654768   0.0359344   
0.0294206   0.0536078   0.0654768   0.0536078   0.0294206   
0.0161464   0.0294206   0.0359344   0.0294206   0.0161464 

(This is just an example of of a Gaussian filter layout).

Here the output layout I am getting in my program:

0.114986 0.101475 0.069743 0.037331 0.015562
0.101475 0.089551 0.061548 0.032944 0.013733
0.069743 0.061548 0.042301 0.022642 0.009439
0.037331 0.032944 0.022642 0.012119 0.005052 
0.015562 0.013733 0.009439 0.005052 0.002106

Here is the code segment of my program:

for (i = 0; i < smooth_kernel_size; i++) {
    for (j = -0; j < smooth_kernel_size; j++) {
        gauss[i][j] = K * exp(((pow((i), 2) + pow((j), 2)) / ((2 * pow(sigma, 2)))) * (-1));
        sum += gauss[i][j]; 
    }
}
for (i = 0; i < smooth_kernel_size; i++) {
    for (j = 0; j < smooth_kernel_size; j++) {
        gauss[i][j] /= sum;
    }
}
for (i = 0; i < smooth_kernel_size; i++) {
    for (j = 0; j < smooth_kernel_size; j++) {
        printf("%f ", gauss[i][j]);
    }
    printf("\n");
}

Will appreciate any advice!

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Brody Gore
  • 77
  • 2
  • 11

2 Answers2

3

Well the problem is with the way you calculate the gaussian filter you should use symmetric points i suppose -2 -1 0 1 2 for eg, Second i think tht's the correct formula

int length = smooth_kernel_size/2;
for (int i = -length ; i <=length ; i++)
    {
        for(int j=-length ; j <=length ; j++)
        {   //here
            gauss[i+length][j+length]= K * exp(-1*((pow((i), 2) + pow((j), 2)) / ((2 * pow(sigma, 2))))) / (M_PI * 2 * pow(sigma, 2));
            sum += gauss[i + length][j +length];
        }
    }
Spinkoo
  • 2,080
  • 1
  • 7
  • 23
3

Your computation is incorrect: the filter should be centered on the origin. Here is a corrected version:

#include <math.h>
#include <stdio.h>

#define smooth_kernel_size 5
#define sigma 1.0
#define K  1

int main() {
    double gauss[smooth_kernel_size][smooth_kernel_size];
    double sum = 0;
    int i, j;

    for (i = 0; i < smooth_kernel_size; i++) {
        for (j = 0; j < smooth_kernel_size; j++) {
            double x = i - (smooth_kernel_size - 1) / 2.0;
            double y = j - (smooth_kernel_size - 1) / 2.0;
            gauss[i][j] = K * exp(((pow(x, 2) + pow(y, 2)) / ((2 * pow(sigma, 2)))) * (-1));
            sum += gauss[i][j];
        }
    }
    for (i = 0; i < smooth_kernel_size; i++) {
        for (j = 0; j < smooth_kernel_size; j++) {
            gauss[i][j] /= sum;
        }
    }
    for (i = 0; i < smooth_kernel_size; i++) {
        for (j = 0; j < smooth_kernel_size; j++) {
            printf("%f ", gauss[i][j]);
        }
        printf("\n");
    }
    return 0;
}

output:

0.002969 0.013306 0.021938 0.013306 0.002969
0.013306 0.059634 0.098320 0.059634 0.013306
0.021938 0.098320 0.162103 0.098320 0.021938
0.013306 0.059634 0.098320 0.059634 0.013306
0.002969 0.013306 0.021938 0.013306 0.002969

Note also that the main expression can be simplified:

    gauss[i][j] = K * exp(-(x * x + y * y) / (2 * sigma * sigma));
chqrlie
  • 131,814
  • 10
  • 121
  • 189