/* +-------------------------------------------------------------------+ */ /* | IMCC csi.ull.es Curso 1999-2000 | */ /* | splitpnm2pat.c y ressplit2pgm | */ /* | | */ /* | splitpnm2pat.c: | */ /* | Transforma un conjunto de ficheros graficos pnm (pbm, pgm o ppm) | */ /* | a un fichero de patrones snns partiendo los ficheros en matrices | */ /* | de un tamaño determinado. | */ /* | | */ /* | ressplit2pgm: (link a splitpnm2pat) | */ /* | A partir de un fichero de resultados snns (solo salidas) genera | */ /* | una imagen pgm fusionando la particion de imagenes realizada | */ /* | mediante splitpnm2pat. | */ /* | | */ /* +-------------------------------------------------------------------+ */ /* +-------------------------------------------------------------------+ */ /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */ /* | | */ /* | Permission to use, copy, modify, and to distribute this software | */ /* | and its documentation for any purpose is hereby granted without | */ /* | fee, provided that the above copyright notice appear in all | */ /* | copies and that both that copyright notice and this permission | */ /* | notice appear in supporting documentation. There is no | */ /* | representations about the suitability of this software for | */ /* | any purpose. this software is provided "as is" without express | */ /* | or implied warranty. | */ /* | | */ /* +-------------------------------------------------------------------+ */ #include #include #include #include "libpnmrw.h" #include "hermat.h" #define MAX_SIZE 255 #define NUM_LINE 10 #define TRUE 1 #define FALSE 0 char *program; void error(char *msg) { fprintf(stderr,"%s: %s\n", program, msg); } unsigned int num_pat; /* Número de patrones esperados */ unsigned int num_pat_real = 0; /* Número de patrones reales */ int cab = 1; /* Imprime cabecera? */ int no_superv = 0; /* Opción no supervizado */ int ascii = FALSE; /* Fichero de salida pgm ascii */ int train = 0; /* Toma subimagenes solapadas (cto. enetrenameinto) */ char dummy[MAX_SIZE]; /* Variable dummy */ void printcab(FILE *fstream, unsigned int num_pat, unsigned int size) { time_t t; if (cab) { time(&t); fprintf(fstream, "SNNS pattern definition file V1.4\n"); fprintf(fstream, "generated at %s\n\n", ctime( &t)); fprintf(fstream, "No. of patterns : %d\n", num_pat); fprintf(fstream, "No. of input units : %d\n", size); fprintf(fstream, "No. of output units : %d\n\n", (no_superv?0:size)); } } int readcab(FILE *fstream, char *version, char * dia, unsigned int *num_pat, unsigned int *num_iuni, unsigned int *num_ouni, unsigned int *starp, unsigned int *endp) { if (fscanf(fstream, "SNNS result file %[^\n]\n", version) != 1) { return (1); } if (fscanf(fstream, "generated at %[^\n]\n\n", dia) != 1) { return (1); } if (fscanf(fstream, "No. of patterns%[ :]%u\n", dummy, num_pat) != 2) { return (1); } if (fscanf(fstream, "No. of input units%[ :]%u\n", dummy, num_iuni) != 2) { return (1); } if (fscanf(fstream, "No. of output units%[ :]%u\n\n", dummy, num_ouni) != 2) { return (1); } if (fscanf(fstream, "startpattern%[ :]%u\n", dummy, starp) != 2) { return (1); } if (fscanf(fstream, "endpattern%[ :]%u\n", dummy, endp) != 2) { return (1); } return (0); } int Read1res(FILE *fd, float * res) { do { fscanf(fd,"%s", dummy); if (dummy[0]== '#') { if (fscanf(fd,"%[^\n]", dummy) == EOF) { return(EOF); } } else { break; } } while (1); if (sscanf(dummy, "%f", res) == EOF) { return(EOF); } return (1); } int ReadRES(FILE *fd, char *name, char *comment, matriz *ptimg, unsigned int wth, unsigned int hth, unsigned int oww, unsigned int ohh) { unsigned int x, y; unsigned int maxval = 255; int coderr = 0; matriz img = *ptimg; float val; char version[MAX_SIZE], dia[MAX_SIZE]; unsigned int num_iuni, num_ouni, starp, endp; wth = (unsigned int) ceil((double) wth/oww) * oww; if (readcab(fd, version, dia, &num_pat, &num_iuni, &num_ouni, &starp, &endp) != 0) { error("formato de fichero inadecuado"); return(2); } num_pat = endp - starp + 1; /* Forma correcta de calcular num_pat */ sprintf(comment, "SNNS result file %s (%s), par(%u, %u, %u, %u, %u)", name, dia, num_pat, num_iuni, num_ouni, starp, endp); if ((num_ouni != oww * ohh) || ((num_pat * num_ouni) < (wth * hth))) { error("ancho y/o alto de submatrices inadecuado"); return(4); } *ptimg = img = reserva_matriz(num_ouni, num_pat); for (y = 0; y < num_pat; y++) { for ( x = 0; x < num_ouni; x++) { if (Read1res(fd, &val) == EOF) { error("ancho y/o alto de submatrices inadecuado"); return(4); } val = (val > 1.0) ? 1.0 : ((val < 0.0) ? 0.0 : val); img[x][y] = val * maxval; num_pat_real++; } } return(coderr); } int ReadPNM(FILE *fd, char *name, FILE *fstreamout, matriz *ptimg, unsigned int *wwin, unsigned int *hhin, unsigned int oww, unsigned int ohh, char *tipcar) { unsigned int x, y; xel **els = NULL; xel *curel; xelval maxval; int pnm_type; int format; unsigned int wth, hth; int coderr = 0; matriz img = *ptimg; pnm_init2(name); if ((els = pnm_readpnm(fd, &wth, &hth, &maxval, &format)) == NULL) { error("formato de fichero inadecuado"); return(2); } pnm_type = PNM_FORMAT_TYPE(format); if ((*wwin == 0) && (*hhin == 0)) { *wwin = wth; *hhin = hth; *ptimg = img = reserva_matriz(wth + oww, hth + ohh); if (train) { num_pat = num_pat * (wth - oww + 1) * (hth - ohh + 1); } else { num_pat = num_pat * (unsigned int) ceil((double) wth/oww) * (unsigned int) ceil((double) hth/ohh); } printcab(fstreamout, num_pat, (oww * ohh)); } else if ((*wwin != wth) || (*hhin != hth)) { libera_matriz(wth + oww, img); *wwin = wth; *hhin = hth; *ptimg = img = reserva_matriz(wth + oww, hth + ohh); coderr = 1; } switch (pnm_type) { case PPM_TYPE: *tipcar='p'; break; case PGM_TYPE: *tipcar='g'; break; case PBM_TYPE: *tipcar='b'; break; } for (y = 0; y < hth; y++) { for (curel = els[y], x = 0; x < wth; curel++, x++) { if (pnm_type == PPM_TYPE) { img[x][y] = (float) (PPM_GETR(*curel) + PPM_GETG(*curel) + PPM_GETB(*curel)) / (maxval * 3); } else if (pnm_type == PGM_TYPE) { img[x][y] = (float) PNM_GET1(*curel) / maxval; } else { img[x][y] = (PNM_GET1(*curel) != PBM_WHITE) ? 1.0 : 0.0; } } } pnm_freearray(els, hth); return(coderr); } void Splitimg(char *name, FILE *fh, matriz img, unsigned int ww, unsigned int hh, unsigned int oww, unsigned int ohh, char tipcar) { unsigned int x, y, ox, oy; fprintf(fh, "\n#Pattern %s (p%cm %dx%d => pat %dx%d):\n", name, tipcar,ww, hh, oww, ohh); for (y = 0; y < (train?(hh-ohh+1):hh);) { for (x = 0; x < (train?(ww-oww+1):ww);) { fprintf(fh, "\n# Input submatrix %d,%d:\n", x, y); for (oy = 0; oy < ohh; oy++) { for (ox = 0; ox < oww; ox++) { fprintf(fh, "%.5f%c", img[x+ox][y+oy], (((ox+oy*ohh+1) % NUM_LINE)?' ':'\n')); } } num_pat_real++; if (!no_superv) { fprintf(fh, "\n# Output submatrix %d,%d:\n", x, y); for (oy = 0; oy < ohh; oy++) { for (ox = 0; ox < oww; ox++) { fprintf(fh, "%.5f%c", img[x+ox][y+oy], (((ox+oy*ohh+1) % NUM_LINE)?' ':'\n')); } } } x += (train?1:oww); } y += (train?1:ohh); } } void Splitres (char *name, FILE *fh, char * comment, matriz img, unsigned int ww, unsigned int hh, unsigned int oww, unsigned int ohh) { xel **xels; unsigned int ni, i, x, y, ox, oy, xo, yo; unsigned char ip; int format; ni = num_pat / ((unsigned int) ceil((double) ww/oww) * (unsigned int) ceil((double) hh/ohh)); format = PGM_FORMAT; pnm_init2(name); xels = pnm_allocarray(ww, ni * hh); for (i=0, yo = 0; i < ni; i++) { for (y = 0; y < hh;) { for (x = 0; x < ww; yo++) { for (oy = 0, xo = 0; oy < ohh; oy++) { for (ox = 0; ox < oww; ox++, xo++) { if ((x+ox < ww) && (y+oy < hh)) { ip = (unsigned char)img[xo][yo]; PPM_ASSIGN(xels[i*hh+y+oy][x+ox], ip, ip, ip); } } } x += oww; } y += ohh; } } /* fprintf(fh, "#%s\n", comment); */ pnm_writepnm(fh, xels, ww, ni * hh, 255, format, ascii); /* si campo ascii a TRUE escirbe un ascci, si no raw */ pnm_freearray(xels, hh); } void help() { if (SPLIT) { /*split*/ fprintf(stderr, "Uso: %s [-c] [-t] [-u] [-s anchoxalto] [-o fdest] file1 file2 ... filen\n", program); fprintf(stderr, "A partir de uno o varios ficheros pnm genera un fichero de patrones snns (pat) mediante la division en submatrices de igual tamaño.\n"); fprintf(stderr, "Opciones:\n"); fprintf(stderr, "\t-c: No incluye cabecera de patrones\n"); fprintf(stderr, "\t-t: Toma las subimágenes solapadas\n"); fprintf(stderr, "\t-u: No supervizado, no genera patrones de deseados\n"); fprintf(stderr, "\t-o fdest: Salida hacia el fichero fdest\n"); fprintf(stderr, "\t-s anchoxalto: Divide las imágenes en altoxancho (8x8)\n"); } else { fprintf(stderr, "Uso: %s [-a] [-s anchoxalto] [-t anchoxalto] [-o fdest] file\n", program); fprintf(stderr, "A partir de un fichero de resultados snns (res) solo con las salidas generado a partir de un fichero de patrones obtenidos con splitpnm2pat construye una imagen tipo pgm.\n"); fprintf(stderr, "Opciones:\n"); fprintf(stderr, "\t-a: Fichero destino tipo ascii\n"); fprintf(stderr, "\t-s anchoxalto: Tamaño de las subimagenes (8x8)\n"); fprintf(stderr, "\t-t anchoxalto: Tamaño de cada imagen original (128x128)\n"); fprintf(stderr, "\t-o fdest: Salida hacia el fichero fdest\n"); } exit(-1); } int main(int argc, char **argv) { extern char *optarg; extern int optind; char c; int coderr = 0; char tipcar; /* Tipo de fichero de entrada */ unsigned int ww = 0; /* width */ unsigned int hh = 0; /* height */ unsigned int oww = 8; /* Ancho de imagen destino */ unsigned int ohh = 8; /* Alto de imagen destino */ matriz img; /* Imagen */ char filedest[MAX_SIZE]; char comment[MAX_SIZE]; FILE *fi; FILE *fh = stdout; program = argv[0]; if (SPLIT) { /*split*/ while ((c = getopt(argc, argv, "ctuo:s:h")) != -1) switch (c) { case 'c': cab = !cab; break; case 't': train = !train; break; case 'u': no_superv = !no_superv; break; case 'o': sscanf(optarg, "%s", &filedest); if ((fh = fopen(filedest, "w"))==NULL) { perror(program); return(1); } break; case 's': sscanf(optarg, "%dx%d", &oww, &ohh); break; case 'h': help(); return(0); break; default: error("parametros inadecuados"); return(1); } if (optind >= argc) { num_pat = 1; fi = stdin; coderr |= ReadPNM(fi, "stdin", fh, &img, &ww, &hh, oww, oww, &tipcar); if (coderr > 1) { return(1); } Splitimg("stdin", fh, img, ww, hh, oww, ohh, tipcar); } else { num_pat = argc - optind; while (optind < argc) { if ((fi = fopen(argv[optind], "r")) == NULL) { perror(program); return(1); } coderr |= ReadPNM(fi, argv[optind], fh, &img, &ww, &hh, oww, oww, &tipcar); if (coderr > 1) { return(1); } fclose(fi); Splitimg(argv[optind], fh, img, ww, hh, oww, ohh, tipcar); optind++; } } switch (coderr) { case 2: return(1); case 1: if (num_pat_real != num_pat) { char coment[200]; sprintf(coment, "Alto y ancho no coinciden entre los distintos ficheros, modificar campo \"No. of patterns\" de la cabecera del fichero de patrones y colocar %d", num_pat_real); error(coment); } } } else { ww = hh = 128; while ((c = getopt(argc, argv, "ao:s:t:h")) != -1) switch (c) { case 'a': ascii = TRUE; break; case 'o': sscanf(optarg, "%s", &filedest); if ((fh = fopen(filedest, "w"))==NULL) { perror(program); return(1); } break; case 's': sscanf(optarg, "%dx%d", &oww, &ohh); break; case 't': sscanf(optarg, "%dx%d", &ww, &hh); break; case 'h': help(); return(0); break; default: error("parametros inadecuados"); return(1); } if (optind == argc) { fi = stdin; } else { if ((optind + 1) == argc) { if ((fi = fopen(argv[optind], "r")) == NULL) { perror(program); return(1); } } else { error("parametros inadecuados"); return(1); } } coderr |= ReadRES(fi, ((optind > argc)?"stdin":argv[optind]), comment, &img, ww, hh, oww, ohh); if (coderr > 1) { return(1); } Splitres(((optind > argc)?"stdin":argv[optind]), fh, comment, img, ww, hh, oww, ohh); } return(0); }