尝试在C中实现高斯滤波器

时间:2019-02-10 07:05:50

标签: c gaussian

我试图在C语言中实现高斯滤波器。我的输出布局总是出错,我尝试在for循环中处理行和列,但是没有用。输出布局应如下所示:

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 

(这只是高斯滤波器布局的一个示例)。

这是我在程序中得到的输出布局:

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

这是我程序的代码段:

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");
}

将感谢您的任何建议!

2 个答案:

答案 0 :(得分:2)

问题是计算高斯滤波器的方式应该使用对称点,我想例如-2 -1 0 1 2 其次,我认为这是正确的公式

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];
        }
    }

答案 1 :(得分:1)

您的计算不正确:过滤器应以原点为中心。这是更正的版本:

#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;
}

输出:

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

还要注意,可以简化主表达式:

    gauss[i][j] = K * exp(-(x * x + y * y) / (2 * sigma * sigma));