PageRenderTime 441ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/tp2/solucion/tools/tp2diff.c

https://gitlab.com/mcaravario/orga2-tps
C | 202 lines | 138 code | 51 blank | 13 comment | 27 complexity | 8e8f5801872846bd489936d7d1582e64 MD5 | raw file
  1. #include <getopt.h>
  2. #include <highgui.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. const char *nombre_programa;
  6. typedef struct bgr8_t {
  7. unsigned char b,g,r;
  8. } __attribute__((packed)) bgr8_t;
  9. void imprimir_ayuda();
  10. int main(int argc, char **argv) {
  11. int siguiente_opcion;
  12. // Opciones
  13. const char* const op_cortas = "hq";
  14. const struct option op_largas[] = {
  15. { "help", 0, NULL, 'h' },
  16. { "quiet", 0, NULL, 'q' },
  17. { NULL, 0, NULL, 0 }
  18. };
  19. // Flags de opciones
  20. int quiet = 0;
  21. // Guardar nombre del programa para usarlo en la ayuda
  22. nombre_programa = argv[0];
  23. // Si se ejecuta sin parametros ni opciones
  24. if (argc == 1) {
  25. imprimir_ayuda ( );
  26. exit ( EXIT_SUCCESS );
  27. }
  28. // Procesar opciones
  29. while (1) {
  30. siguiente_opcion = getopt_long ( argc, argv, op_cortas, op_largas, NULL);
  31. // No hay mas opciones
  32. if ( siguiente_opcion == -1 )
  33. break;
  34. // Procesar opcion
  35. switch ( siguiente_opcion ) {
  36. case 'h' : /* -h o --help */
  37. imprimir_ayuda ( );
  38. exit ( EXIT_SUCCESS );
  39. break;
  40. case 'q' : /* -q o --quiet */
  41. quiet = 1;
  42. break;
  43. case '?' : /* opcion no valida */
  44. imprimir_ayuda ( );
  45. exit ( EXIT_SUCCESS );
  46. default : /* opcion no valida */
  47. abort ( );
  48. }
  49. }
  50. const char *filename_a = argv[optind++];
  51. if (filename_a == NULL) {
  52. imprimir_ayuda ( );
  53. exit ( EXIT_SUCCESS );
  54. }
  55. const char *filename_b = argv[optind++];
  56. if (filename_b == NULL) {
  57. imprimir_ayuda ( );
  58. exit ( EXIT_SUCCESS );
  59. }
  60. const char *epsilon_str = argv[optind++];
  61. if (epsilon_str == NULL) {
  62. imprimir_ayuda ( );
  63. exit ( EXIT_SUCCESS );
  64. }
  65. int epsilon = atoi(epsilon_str);
  66. // Cargo las imagenes
  67. IplImage *src_a = 0;
  68. IplImage *src_b = 0;
  69. IplImage *dst = 0;
  70. int width;
  71. int height;
  72. if( (src_a = cvLoadImage (filename_a, CV_LOAD_IMAGE_UNCHANGED)) == 0 )
  73. {
  74. printf("Error al cargar: %s\n", filename_a);
  75. exit(EXIT_FAILURE);
  76. }
  77. if( (src_b = cvLoadImage (filename_b, CV_LOAD_IMAGE_UNCHANGED)) == 0 )
  78. {
  79. printf("Error al cargar: %s\n", filename_b);
  80. cvReleaseImage(&src_a);
  81. exit(EXIT_FAILURE);
  82. }
  83. // Chequear tamanos de las imagenes
  84. if (src_a->width != src_b->width || src_a->height != src_b->height) {
  85. printf("Los tamaños de las imágenes no distintos.\n");
  86. cvReleaseImage(&src_a);
  87. cvReleaseImage(&src_b);
  88. exit(EXIT_FAILURE);
  89. }
  90. // Creo una IplImage para cada salida esperada
  91. if( (dst = cvCreateImage (cvGetSize(src_a), IPL_DEPTH_8U, 1) ) == 0 ) {
  92. printf("Error al crear imágen de salida.\n");
  93. cvReleaseImage(&src_a);
  94. cvReleaseImage(&src_b);
  95. exit(EXIT_FAILURE);
  96. }
  97. // Chequeo pixel a pixel
  98. width = src_a->width;
  99. height = src_a->height;
  100. int row_size_a = src_a->widthStep;
  101. int row_size_b = src_b->widthStep;
  102. int row_size_dst = dst->widthStep;
  103. int equal = 1;
  104. unsigned char (*src_a_matrix)[row_size_a] = (unsigned char (*)[row_size_a]) src_a->imageData;
  105. unsigned char (*src_b_matrix)[row_size_b] = (unsigned char (*)[row_size_b]) src_b->imageData;
  106. unsigned char (*dst_matrix)[row_size_dst] = (unsigned char (*)[row_size_dst]) dst->imageData;
  107. for (int i = 0; i<height; i++) {
  108. for (int j = 0; j<width; j++) {
  109. bgr8_t *p_a = (bgr8_t*) &src_a_matrix[i][j*3];
  110. bgr8_t *p_b = (bgr8_t*) &src_b_matrix[i][j*3];
  111. if (abs(p_a->r - p_b->r) > epsilon ||
  112. abs(p_a->g - p_b->g) > epsilon ||
  113. abs(p_a->b - p_b->b) > epsilon)
  114. {
  115. if (!quiet) {
  116. printf("Hay diferencias en el pixel: (%4d, %4d) ", i, j);
  117. printf("[b %2x, g %2x, r %2x] vs. [b %2x, g %2x, r %2x]\n",
  118. p_a->b, p_a->g, p_a->r, p_b->b, p_b->g, p_b->r);
  119. }
  120. equal = 0;
  121. dst_matrix[i][j] = 255;
  122. } else {
  123. dst_matrix[i][j] = 0;
  124. }
  125. }
  126. }
  127. // Guardo imagen y libero las imagenes
  128. char nomb_arch_salida[256];
  129. memset(nomb_arch_salida, 0, 256);
  130. sprintf(nomb_arch_salida, "diferencia.bmp");
  131. cvSaveImage(nomb_arch_salida, dst, NULL);
  132. // Libero las imagenes
  133. cvReleaseImage(&src_a);
  134. cvReleaseImage(&src_b);
  135. cvReleaseImage(&dst);
  136. return !equal;
  137. }
  138. void imprimir_ayuda ( ) {
  139. printf ( "Uso: %s opciones nombre_archivo_entrada_a nombre_archivo_entrada_b epsilon \n", nombre_programa );
  140. printf ( "Ejemplo de uso: \n" );
  141. printf ( " %s lena_a.bmp lena_b.bmp 5 \n", nombre_programa );
  142. printf ( " \n" );
  143. printf ( " Verifica pixel a pixel que la diferencia entre lena_a.bmp y \n" );
  144. printf ( " lena_b.bmp no supere el valor 5. Genera una imágen a partir \n" );
  145. printf ( " de las diferencias, poniendo un pixel blanco donde haya \n" );
  146. printf ( " diferencias y uno negro donde no. \n" );
  147. printf ( " \n" );
  148. printf ( " -h, --help Imprime esta ayuda \n" );
  149. printf ( " \n" );
  150. printf ( " -q, --quiet Ejecuta en modo silencioso. \n" );
  151. }