Попытка реализовать фильтр Гаусса в C - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь реализовать фильтр Гаусса в 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 голосов
/ 10 февраля 2019

Ваши вычисления неверны: фильтр должен быть центрирован на источнике.Вот исправленная версия:

#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));
0 голосов
/ 10 февраля 2019

Ну, проблема в том, как вы вычисляете гауссов фильтр, вы должны использовать симметричные точки, я полагаю, -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];
        }
    }
...