#include #include #include extern void escalaDeGrises(char* datos, unsigned filas, unsigned columnas); extern void escalaDeGrises2(char* datos, unsigned filas, unsigned columnas); extern void prewitt_asm(char* datos, char* copia, unsigned filas, unsigned columnas); extern void sobel_asm(char* datos, char* copia, unsigned filas, unsigned columnas); extern void roberts_asm(char* datos, char* copia, unsigned filas, unsigned columnas); extern void umbralizar_asm(char* datos, unsigned filas, unsigned columnas, unsigned th, unsigned tl); /* r1 = realzar bordes con el operador de Roberts. r2 = realzar bordes con el operador de Prewitt. r3 = realzar bordes con el operador de Sobel. m1 = monocromatizar con = 1. =∞ m2 = monocromatizar con u = umbralizar (en este caso tambien toma dos enteros para los umbrales maximo y minimo) i = input (nombre del archivo) */ // TODO: completar este help y hacer que se imprima cuando hay un error. void help(){ printf("Parametros:\n"); printf("--help (-h) Muestra esta ayuda\n"); printf("--m1 (-m) Convierte a escala de grises con"); printf("promedios\n"); printf("--m2 (-g) Convierte a escala de grises con maximo\n"); printf("--input (-i) Nombre de archivo de entrada"); printf(" (obligatorio)\n"); printf("--output (-o) Nombre de archivo de salida"); printf(" (obligatorio)\n"); printf("--r1 (-r) Deteccion de bordes con el operador de"); printf("Roberts\n"); printf("--r2 (-p) Deteccion de bordes con el operador de"); printf("Prewitt\n"); printf("--r3 (-s) Deteccion de bordes con el operador de"); printf("Sobel\n"); printf("--umbralizar (-u) Aplicar umbralizacion por histeresis. "); printf("Obligatorio: limite\n"); printf(" inferior y superior\n"); printf("Para umbralizar es necesario seleccionar un filtro\n"); printf("Por defecto se monocromatiza con promedios\n"); } int main(int argc, char **argv){ const char* const op_cortas = "hmgrpsi:o:u:" ; // posibles parametros, van //con - int siguiente_opcion; // forma larga para las opciones. En consola van con -- const struct option op_largas[] = { { "m1", 0, NULL, 'm'}, { "m2", 0, NULL, 'g'}, { "input", 1, NULL, 'i'}, { "output", 1, NULL, 'm'}, {"r1", 0, NULL, 'r'}, {"r2", 0, NULL, 'p'}, {"r3", 0, NULL, 's'}, {"umbralizar", 1, NULL, 'u'}, {"help", 0, NULL, 'h'}, { NULL, 0, NULL, 0 } }; // si no puso parametros, le decimos que necesitamos el archivo if (argc == 1) { printf("No se especifico una imagen!\n"); help(); } // declaracion de variables char * ficheroEntrada; // nombre del archivo char * ficheroSalida = NULL; char metodo='m'; // metodo de monocromatizacion char metodoBordes = 'f'; // metodo de deteccion de bordes unsigned min, max; // parametros para umbralizar int umbralizo = 0; // flag de umbralizar while (1) { // llamamos a la función getopt siguiente_opcion = getopt_long (argc, argv, op_cortas, op_largas, NULL); if (siguiente_opcion == -1) // no hay mas opciones break; // para cada parametro, seteamos el flag correspondiente switch (siguiente_opcion) { case 'm' : /* -m o --m1 */ metodo = 'm' ; break; case 'g' : /* -g o --m2 */ metodo = 'g' ; break; case 'r' : /* -r o --r1 */ metodoBordes = 'r' ; break; case 's' : /* -s o --r2 */ metodoBordes = 's' ; break; case 'p' : /* -p o --r3 */ metodoBordes = 'p' ; break; case 'u' : /* -u ó --umbralizar */ umbralizo = 1; sscanf(optarg,"%d",&min); break; case 'i' : /* -i ó --input */ ficheroEntrada = optarg; /* optarg contiene el argumento de -o */ break; case 'o' : /* -o ó --output */ ficheroSalida = optarg; /* optarg contiene el argumento de -o*/ break; case 'h' : /* -h ó --help */ help(); return 0; case -1 : /* No hay más opciones */ break; default : /* Algo más? No esperado. Abortamos */ printf("Formato de opciones invalido!\n"); help(); return 1; } } // Para umbralizar se necesitan 2 parametros. Como getOpt solo toma uno, el otro lo coloca en // los no identificados. Para evitar que se pongan mas de uno, pedimos que solo halla un parametro no // identificado. if(umbralizo && optind == argc -1) sscanf(argv[optind],"%d",&max); // si hay parametros de mas paramos if((!umbralizo && optind < argc) || (umbralizo && optind != argc -1) ) { printf("Formato de opciones invalido!\n"); help(); return 1; } // abrimos el archivo FILE* fichero; FILE* salida; int ancho, alto, offset; char marca1, marca2; if (ficheroSalida == NULL) { puts("No se pudo crear archivo de salida\n"); return 1; } fichero = fopen(ficheroEntrada, "rbw+"); salida = fopen(ficheroSalida, "wb"); if (fichero == NULL) { puts("Archivo no encontrado! Ingreso el nombre correcto?\n"); help(); return 1; } if (salida == NULL) { puts("No se pudo crear archivo de salida\n"); return 1; } else { marca1 = fgetc(fichero); // leemos los dos primeros bytes marca2 = fgetc(fichero); if (marca1 =='B' && marca2 =='M') { // si son BM, sino paramos fseek(fichero, 18, SEEK_SET); // posicion 18: ancho fread(&ancho, 1, 4, fichero); fread(&alto, 1, 4, fichero); // siguiente dato: alto fseek(fichero, 10, SEEK_SET); // tomamos el offset hasta los pixeles fread(&offset,1,4,fichero); short int sumandoextra = (4 - (ancho*3 % 4)) % 4; unsigned int dimension = (ancho * 3 + sumandoextra) * alto; // cada pixel son 24 bits, o sea 3 bytes char * matriz = (char*) malloc(dimension); // memoria para levantar el archivo char * matriz2 = (char*) malloc(dimension); // memoria para guardar los bordes detectados if(matriz != 0) { fseek(fichero, offset, SEEK_SET); fread(matriz, dimension, 1, fichero); // operamos segun los parametros recibidos if(metodo == 'm'){ printf("Monocromatizando...\n"); escalaDeGrises(matriz, alto, 3*ancho); } else if(metodo == 'g'){ printf("Monocromatizando...\n"); escalaDeGrises2(matriz, alto, 3*ancho); } if(metodoBordes == 's') { printf("Aplicando Sobel...\n"); sobel_asm(matriz, matriz2, alto, ancho); } else if (metodoBordes == 'r') { printf("Aplicando Roberts...\n"); roberts_asm(matriz, matriz2, alto, ancho); } else if (metodoBordes == 'p'){ printf("Aplicando Prewitt...\n"); prewitt_asm(matriz, matriz2, alto, ancho); } if(umbralizo && metodoBordes == 'f'){ printf("Para umbralizar se debe aplicar un filtro primero"); printf("\nSeleccione un filtro para poder umbralizar\n"); help(); umbralizo = 0; } if(umbralizo) { // llamada a umbralizar if(min > 255){ printf("Adevertencia: los valores mayores a 255, seran interpretados como 255.\n"); min = 255; } if(max > 255){ printf("Adevertencia: los valores mayores a 255, seran interpretados como 255.\n"); max = 255; } printf("Umbralizando con umbral superior %u y umbral inferior %u ...\n", max, min); umbralizar_asm(matriz2,alto, ancho, max, min); } char * info = (char*) malloc(offset); fseek(fichero, 0, SEEK_SET); fread(info,offset,1,fichero); fwrite(info, offset, 1, salida); fseek(fichero, offset, SEEK_SET); if(metodoBordes != 'f'){ fwrite(matriz2, dimension, 1, salida); } else{ fwrite(matriz, dimension, 1, salida); } fclose(fichero); fclose(salida); free(matriz); free(matriz2); free(info); } } return 0; } }