代码之家  ›  专栏  ›  技术社区  ›  Brody Gore

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

  •  1
  • Brody Gore  · 技术社区  · 6 年前

    我正试图在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 回复  |  直到 6 年前
        1
  •  1
  •   chqrlie    6 年前

    您的计算不正确:过滤器应该位于原点的中心。以下是正确的版本:

    #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));
    
        2
  •  2
  •   Spinkoo    6 年前

    问题在于你计算高斯滤波器的方法,你应该使用对称点,我想-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];
            }
        }