The function should only apply the Gaussian filter in a PPM image, but the result is several superimposed filtered images. Any suggestions?
[edit] before filter image | image after filter | expected result
pixel** gauss_filter(pixel** picture, int* L, int* C)
{
float novopixel = 0.;
float peso = 0.;
int i, j = 0;
int a, b = 0;
float filter[5][5] = {{(2.),(4.),(5.),(4.),(2.)},
{(4.),(9.),(12.),(9.),(4.)},
{(5.),(12.),(15.),(12.),(5.)},
{(4.),(9.),(12.),(9.),(4.)},
{(2.),(4.),(5.),(4.),(2.)}};
pixel** new_picture = (pixel**)malloc(*L * sizeof(pixel*));
for(i = 0; i < *L; i++)
{
new_picture[i] = (pixel*) malloc(*C * sizeof(pixel));
for(j = 0; j < *C; j++)
{
novopixel = 0.;
peso = 0.;
for(a = -2; a <= 2; a++)
{
for(b = -2; b <= 2; b++)
{
if((i+a >= 0 && i+a < *L) && (j+b >= 0 && j+b < *C))
{
//Estou usando uma imagem em tons de cinza
//por isso calculo um canal e repito o valor
//nos outros canais
novopixel += (picture[i+a][j+b].r * filter[a+2][b+2]);
peso += filter[a+2][b+2];
}
}
}
novopixel = novopixel/peso;
new_picture[i][j].r = (int)novopixel;
new_picture[i][j].g = (int)novopixel;
new_picture[i][j].b = (int)novopixel;
}
}
free(picture);
picture = new_picture;
return picture;
}
//======================================================================
pixel** create_picture(FILE *arq, int* L, int* C)
{
int i, j = 0;
//armazena tipo do arquivo
char tipo[3];
//buffer para leitura do arquivo
char line[64];
//controla a leitura do cabecalho
int flag = 0;
int componente = 0;
while ( fgets(line, sizeof line, arq) )
{ //primeira linha: tipo
if(flag == 0)
{
sscanf(line, "%s", tipo);
printf("\ntipo: %s",tipo);
flag += 1;
}
//terceira linha: dimensoes
if(flag == 2)
{
sscanf(line, "%d %d", &*L, &*C);
printf("\nlinhas: %d colunas: %d", *L, *C);
flag +=1;
}
//valor de componente
if(flag == 3)
{
fgets(line, sizeof line, arq);
sscanf(line, "%d", &componente);
printf("\ncomponente: %d", componente);
if(componente != 255)
{
fprintf(stderr, "\nComponente de imagem RGB invalido (%d)\n", componente);
exit(1);
}
break;
}
//segunda linha: comentarios
if(flag == 1)
{
fgets(line, sizeof line, arq);
flag += 1;
}
}
if (tipo[0] != 'P' || tipo[1] != '3')
{
fprintf(stderr, "Formato de arquivo invalido ('%c%c')\n", tipo[0], tipo[1]);
exit(1);
}
pixel** picture = (pixel**)malloc(*L * sizeof(pixel*));
for (i = 0; i < *L; i++)
{
picture[i] = (pixel*) malloc(*C * sizeof(pixel));
for (j = 0; j < *C; j++)
{
fgets(line, sizeof line, arq);
sscanf(line, "%d", &picture[i][j].r);
fgets(line, sizeof line, arq);
sscanf(line, "%d", &picture[i][j].g);
fgets(line, sizeof line, arq);
sscanf(line, "%d", &picture[i][j].b);
}
}
return picture;
}
//=============================================
void output(pixel** picture, int* L, int* C, char* arquivo, char* etapa)
{
int i = 0;
int j = 0;
char name[30] = "";
strcat(name, etapa);
strcat(name, arquivo);
FILE *file = NULL;
file = fopen(name, "w");
//formato da imagem
fprintf(file, "P3\n");
//comentario
fprintf(file, "# Arquivo PPM de saida\n");
//tamanho da imagem
fprintf(file, "%d %d\n", *L, *C);
//componente RGB
fprintf(file, "255\n");
for(i = 0; i < *L; i++)
{
for(j = 0; j < *C; j++)
{
fprintf(file, "%d\n", picture[i][j].r);
fprintf(file, "%d\n", picture[i][j].g);
fprintf(file, "%d\n", picture[i][j].b);
}
}
fclose(file);
}
//============================================
int main()
{
FILE *arq = NULL;
pixel** imagem = NULL;
int linhas = 0;
int colunas = 0;
printf("\nEspecifique o arquivo de imagem a ser analisado: ");
//armazena o nome do arquivo
char *arquivo = (char*) malloc(25 * sizeof(char));
scanf("%s", arquivo);
//Abre o arquivo, e, se nao for possivel, envia mensagem de erro
if ((arq = fopen(arquivo, "r")) == NULL)
{
fprintf(stderr, "\nErro.\nImpossivel abrir arquivo especificado.\n");
exit(1);
}
//imagem original
imagem = create_picture(arq, &linhas, &colunas);
output(imagem, &linhas, &colunas, arquivo, "original_");
//imagem filtrada
imagem = gauss_filter(imagem, &linhas, &colunas);
output(imagem, &linhas, &colunas, arquivo, "gauss_");
free(arquivo);
free(arq);
free(imagem);
return 0;
}