Я пытаюсь реализовать Gaussian Blur с нуля (используя C ++). В приведенном ниже коде я жестко запрограммировал используемое гауссовское ядро. Я сохранил только одно измерение, поскольку я пытаюсь использовать оптимизацию, о которой я читал, где вы можете выполнить горизонтальный проход свертки и вертикальный, чтобы сделать размытие более эффективным. К сожалению, у меня возникли некоторые проблемы. Вот мой код:
float gKern[5] = {0.05448868, 0.24420134, 0.40261995, 0.24420134, 0.05448868};
int** gaussianBlur(int** image, int height, int width) {
int **ret = new int*[height];
for(int i = 0; i < height; i++) {
ret[i] = new int[width];
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (i == 0) {
ret[i][j] = (gKern[0] * image[2][j]) + (gKern[1] * image[1][j]) + (gKern[2] * image[0][j]) + (gKern[3] * image[1][j]) + (gKern[4] * image[2][j]);
} else if (i == 1) {
ret[i][j] = (gKern[0] * image[1][j]) + (gKern[1] * image[0][j]) + (gKern[2] * image[1][j]) + (gKern[3] * image[2][j]) + (gKern[4] * image[3][j]);
} else if (i == (height - 2)) {
ret[i][j] = (gKern[0] * image[i - 2][j]) + (gKern[1] * image[i - 1][j]) + (gKern[2] * image[i][j]) + (gKern[3] * image[i + 1][j]) + (gKern[4] * image[i][j]);
} else if (i == (height - 1)) {
ret[i][j] = (gKern[0] * image[i - 2][j]) + (gKern[1] * image[i - 1][j]) + (gKern[2] * image[i][j]) + (gKern[3] * image[i - 1][j]) + (gKern[4] * image[i - 2][j]);
} else {
ret[i][j] = (gKern[0] * image[i - 2][j]) + (gKern[1] * image[i - 1][j]) + (gKern[2] * image[i][j]) + (gKern[3] * image[i + 1][j]) + (gKern[4] * image[i + 2][j]);
}
}
}
int** temp = image;
image = ret;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (j == 0) {
ret[i][j] = (gKern[0] * image[i][2]) + (gKern[1] * image[i][1]) + (gKern[2] * image[i][0]) + (gKern[3] * image[i][1]) + (gKern[4] * image[i][2]);
} else if (j == 1) {
ret[i][j] = (gKern[0] * image[i][1]) + (gKern[1] * image[i][0]) + (gKern[2] * image[i][1]) + (gKern[3] * image[i][2]) + (gKern[4] * image[i][3]);
} else if (j == (width - 2)) {
ret[i][j] = (gKern[0] * image[i][j - 2]) + (gKern[1] * image[i][j - 1]) + (gKern[2] * image[i][j]) + (gKern[3] * image[i][j + 1]) + (gKern[4] * image[i][j]);
} else if (j == (width - 1)) {
ret[i][j] = (gKern[0] * image[i][j - 2]) + (gKern[1] * image[i][j - 1]) + (gKern[2] * image[i][j]) + (gKern[3] * image[i][j - 1]) + (gKern[4] * image[i][j - 2]);
} else {
ret[i][j] = (gKern[0] * image[i][j - 2]) + (gKern[1] * image[i][j - 1]) + (gKern[2] * image[i][j]) + (gKern[3] * image[i][j + 1]) + (gKern[4] * image[i][j + 2]);
}
}
}
image = temp;
return ret;
}
Первый проход (первый для блока), кажется, работает нормально, поскольку, когда я закомментирую второй блок, я получаю слегка размытое изображение. Но когда я использую оба, я получаю прерывистое "странное" изображение, как показано ниже (первое изображение - это мой полутоновый ввод, второй - прерывистый вывод):