////////////////////////////////////////////////////////////////////////// // // Fundamentos de Programación // ETS Informática y Telecomunicaciones // Universidad de Granada // Departamento de Ciencias de la Computación e Inteligencia Artificial // Autor: Juan Carlos Cubero // ////////////////////////////////////////////////////////////////////////// // Imagen suavizada #include using namespace std; /* Se quiere trabajar con una tabla de datos en el que todas las filas tienen el mismo número de columnas y los datos son de tipo int . Esta clase se llamará ImagenBlancoNegro y contendrá valores enteros que representan un nivel de gris (0 sería negro y 255 blanco). Se supone que todos los valores deben ser positivos aunque por problemas de captación y registro algunos de ellos son negativos. Es preciso corregir estos valores erróneos y se propone sustituir- los por el valor promedio (la media_ent aritmética truncada a entero) de sus ocho vecinos más cercanos espacialmente (arriba, abajo, izquierda, derecha y las cuatro esquinas adyacentes). Este es el método conocido como Mean Filter for Smoothing Debe considerar que entre estos vecinos pudiera haber valores negativos, y en este caso no intervendrán en el cálculo del valor promedio: Si hubiera un sólo valor negativo en la vecindad, se sumarán los valores de los 7 vecinos válidos y la suma se dividirá entre 7. Si hubiera dos valores negativos en la vecindad, se sumarán los valores de los 6 vecinos válidos y la suma se dividirá entre 6. ...Si no hubiera ningún valor válido, se sustituirá por un cero. Implemente un método para que dada una imagen, devuelva otra imagen corregida. La imagen original no se modifica. Para la implementación debe considerar: a) El algoritmo debe ser simple y claro. b) Para simplificar el problema, las casillas de los bordes no se modifican, aunque sí se usan para efectuar las correcciones oportunas. En definitiva, la primera y la última fila así como la primera y la última columna son iguales entre la ma- triz original y la corregida (por lo que podrían quedar valores negativos en estas posiciones). Cree un programa principal de prueba que lea el tamaño de la imagen (filas y colum- nas) y los datos correspondientes. El programa debe construir la imagen suavizada e imprimir el resultado en pantalla. Ejemplo de entrada: 5 6 -1 -1 -1 1 9 1 -2 -1 -1 8 -1 1 -1 -1 -1 1 3 1 -1 -1 -1 4 4 4 1 5 5 5 5 1 -- Salida correcta: -1 -1 -1 1 9 1 -2 0 3 8 3 1 -1 0 4 1 3 1 -1 3 4 4 4 4 1 5 5 5 5 1 */ int main(){ const int MAX_FIL = 100; const int MAX_COL = 100; int imagen[MAX_FIL][MAX_COL], imagen_suavizada[MAX_FIL][MAX_COL]; int util_fil, util_col, num_vecinos_correctos; int media_ent; cout << "Imagen Suavizada\n" << "Introduzca número de filas, número de columnas y luego los valores de la imagen\n"; do{ cin >> util_fil; }while (! (util_fil > 0 && util_fil < MAX_FIL)); do{ cin >> util_col; }while (! (util_col > 0 && util_col < MAX_COL)); for (int fil = 0; fil < util_fil; fil++) for (int col = 0; col < util_col; col++){ cin >> imagen[fil][col]; imagen_suavizada[fil][col] = imagen[fil][col]; } for (int fil = 1 ; fil < util_fil - 1; fil++){ for (int col = 1; col < util_col - 1; col++){ if (imagen[fil][col] < 0){ // (*) media_ent = 0; num_vecinos_correctos = 0; for (int i = fil - 1; i <= fil + 1; i++){ for (int j = col - 1; j <= col + 1; j++){ if (! (i == fil && j == col)){ // (**) if (imagen[i][j] >= 0){ // (***) media_ent = media_ent + imagen[i][j]; num_vecinos_correctos++; } } } } if (num_vecinos_correctos > 0){ media_ent = media_ent / num_vecinos_correctos; imagen_suavizada[fil][col] = media_ent; } else imagen_suavizada[fil][col] = 0; } } } /* La condición (**) controla que no se considere como vecino de fil, col la misma casilla fil, col. Nos lo podríamos haber ahorrado ya que tenemos la garantía de que imagen[fil][col] es un valor negativo (*), por lo que la condición (***) será falsa y no corremos el peligro de computar el valor en la media. Sin embargo, el código queda más claro dejando la condición (**) y no depende de posibles cambios de criterios en el futuro. Hay cierto código duplicado ya que la comprobación de si un pixel es correcto se realiza en dos sitios: (*) y (***). Lo correcto sería empaquetar ese código en un módulo. Lo veremos en el tema IV. */ //////////////////////////////////////////////////////// cout << "\nImagen original:\n"; for (int i = 0; i < util_fil; i++){ for(int j = 0; j < util_col; j++) cout << imagen[i][j] << " "; cout << "\n"; } cout << "\n\nImagen suavizada:\n"; for (int i = 0; i < util_fil; i++){ for(int j = 0; j < util_col; j++) cout << imagen_suavizada[i][j] << " "; cout << "\n"; } // 5 6 -1 -1 -1 1 9 1 -2 -1 -1 8 -1 1 -1 -1 -1 1 3 1 -1 -1 -1 4 4 4 1 5 5 5 5 1 // -1 -1 -1 1 9 1 -2 0 3 8 3 1 -1 0 4 1 3 1 -1 3 4 4 4 4 1 5 5 5 5 1 /* Imagen original: -1 -1 -1 1 9 1 -2 -1 -1 8 -1 1 -1 -1 -1 1 3 1 -1 -1 -1 4 4 4 1 5 5 5 5 1 Imagen suavizada: -1 -1 -1 1 9 1 -2 0 3 8 3 1 -1 0 4 1 3 1 -1 3 4 4 4 4 1 5 5 5 5 1 */ }