📙 Matrices - Java#

  • 1 - Instalar Java

  • 2 - Ejemplos Matrices

  • 3 - Ejercicios

Instalar Java#

Descargar el kernel

Ejecuta la siguiente celda. No la modifiques!

!wget -q -O "Grayscale_Lena.png" "https://raw.githubusercontent.com/BioAITeamLearning/prog1-2023-02-ucaldas/main/content/imgs/Grayscale_Lena.png"
%%sh
wget -q https://github.com/SpencerPark/IJava/releases/download/v1.3.0/ijava-1.3.0.zip
unzip -q ijava-1.3.0.zip
python install.py

wget -qO- https://gist.github.com/SpencerPark/e2732061ad19c1afa4a33a58cb8f18a9/archive/b6cff2bf09b6832344e576ea1e4731f0fb3df10c.tar.gz | tar xvz --strip-components=1
python install_ipc_proxy_kernel.py --kernel=java --implementation=ipc_proxy_kernel.py
---------------------------------------------------------------------------
io.github.spencerpark.jupyter.kernel.magic.registry.UndefinedMagicException: Undefined cell magic 'sh'
	at io.github.spencerpark.jupyter.kernel.magic.registry.Magics.applyCellMagic(Magics.java:34)
	at io.github.spencerpark.ijava.runtime.Magics.cellMagic(Magics.java:31)
	at .(#12:1)

Instrucciones para activar el kernel

Dirigite a Entorno de ejecución > Cambiar tipo de entorno de ejecución > Elige la opción Java > Da click en Guardar

Importar Librerias#

// Libreria para usar potencia y otras funciones matemáticas
import java.lang.Math;

// Libreria para usar el objeto Scanner (leer variables)
import java.util.Scanner;

// Libreria para usar el objeto Random (números aleatorios)
import java.util.Random;

Ejemplos Matrices#

Una matriz es una estructura de datos bidimensional que nos permite almacenar datos de un mismo tipo. Su tamaño es fijo.

Recodermos que una matriz tiene filas y columnas, por lo tanto cada posición de la matriz tiene una pareja de indices: [fila][columna]

image.png

La matriz anterior tiene un tamaño \(m\times n\) igual a \(2\times4\).

Nota. Al igual que en los arreglos los indices inician en \(0\)

Sintaxis#

Primera forma:

image.png

Segunda Forma:

image.png

Ejemplo 1.

Utilizando la primera sintaxis, crear una matriz de enteros de tamaño \((6\times2)\) y asignar valores.

// Declaración y creacióm
int[][] matrizEnteros = new int[6][2];

// Asignación de valores
matrizEnteros[0][0] = 4;
matrizEnteros[0][1] = 3;
matrizEnteros[1][0] = 56;
matrizEnteros[1][1] = 21;
matrizEnteros[2][0] = 67;
matrizEnteros[2][1] = -4;
matrizEnteros[3][0] = -23;
matrizEnteros[3][1] = -3;
matrizEnteros[4][0] = 0;
matrizEnteros[4][1] = 12;
matrizEnteros[5][0] = 10;
matrizEnteros[5][1] = 20;
20

Ahora veamos los numeros en algunas posiciones:

// Fila 4, Columna 1 (no confundir con indices)
System.out.println(matrizEnteros[3][0])
-23
// Fila 1, Columna 2
System.out.println(matrizEnteros[0][1])
3

¿Qué ocurre cuando intentamos acceder a una posición que no existe?

// Fila 6, Columna 4
System.out.println(matrizEnteros[5][3])
---------------------------------------------------------------------------
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 2
	at .(#31:2)

Java nos dice que el indice 3 está fuera de rango para un tamaño/longitud de 2, es decir, hay dos columnas pero intentamos acceder a una tercera.

¿Cómo podemos conocer el tamaño de una matriz, es decir, el valor para \(m\) y \(n\)?

System.out.println("Número de Filas (m): " + matrizEnteros.length);
Número de Filas (m): 6
/*
Conociendo el número de filas (6) accedemos a cualquier indice de fila
(0 a 5 en este caso) y encontramos su longitud, es decir, el número de elementos
en la fila.
*/
System.out.println("Número de Columnas (n): " + matrizEnteros[5].length);
System.out.println("Número de Columnas (n): " + matrizEnteros[0].length);
Número de Columnas (n): 2
Número de Columnas (n): 2

Ejemplo 2

Utilizando las dos sintaxis, crear una matriz de Strings de tamaño \((2\times3)\) y asignar valores.

// Primera Sintaxis //

// Declaración y creación
String[][] nombresEstudiantes = new String[2][3];

// Asignación de valores
nombresEstudiantes[0][0] = "Juan";
nombresEstudiantes[0][1] = "Pedro";
nombresEstudiantes[0][2] = "Pablo";
nombresEstudiantes[1][0] = "Maria";
nombresEstudiantes[1][1] = "Ana";
nombresEstudiantes[1][2] = "Sara";
Sara
// Segunda Sintaxis //

// Declaración, creación y asignación
String[][] nombresEstudiantes2 = {
                                  {"Juan", "Pedro", "Pablo"},
                                  {"Maria", "Ana", "Sara"}
                                };

La forma de declarar, crear y asignar valores a una matriz depende del contexto en el que la vas a usar. Si ya conoces los valores, la segunda forma es la más indicada.




Ahora, sería útil crear funcionnes que impriman los valores de una matriz, la cual recibará la matriz pero retornará nada. Por el momento crearemos 3 funciones para tipos de datos entero, double, flotante y String:

int ANCHO_ELEMENTO_NUMS = 10, ANCHO_ELEMENTO_STR = 10;

public static void imprimirMatrizInt(int[][] matriz) {
  for (int fil = 0; fil < matriz.length; fil++) {
    for (int col = 0; col < matriz[fil].length; col++) {
      System.out.printf("%-" + ANCHO_ELEMENTO_NUMS + "d", matriz[fil][col]);
    }
    System.out.println("");
  }
}

public static void imprimirMatrizFloat(float[][] matriz) {
  for (int fil = 0; fil < matriz.length; fil++) {
    for (int col = 0; col < matriz[fil].length; col++) {
      System.out.printf("%-" + ANCHO_ELEMENTO_NUMS + ".3f", matriz[fil][col]);
    }
    System.out.println("");
  }
}

public static void imprimirMatrizDouble(double[][] matriz) {
  for (int fil = 0; fil < matriz.length; fil++) {
    for (int col = 0; col < matriz[fil].length; col++) {
      System.out.printf("%-" + ANCHO_ELEMENTO_NUMS + ".3f", matriz[fil][col]);
    }
    System.out.println("");
  }
}

public static void imprimirMatrizString(String[][] matriz) {
  for (int fil = 0; fil < matriz.length; fil++) {
    for (int col = 0; col < matriz[fil].length; col++) {
      System.out.printf("%-" + ANCHO_ELEMENTO_STR + "s", matriz[fil][col]);
    }
    System.out.println("");
  }
}

Probemos las funciones con las matrices creadas anteriormente:

imprimirMatrizString(nombresEstudiantes);
Juan      Pedro     Pablo     
Maria     Ana       Sara      
imprimirMatrizInt(matrizEnteros);
4      3      
56     21     
67     -4     
-23    -3     
0      12     
10     20     

Ejemplo 3.

Pide por teclado el numero de filas y columnas, crea una matriz de double y asigna los valores por teclado nuevamente.

Utiliza las funciones creadas anteriormente para imprimir la matriz resultante.

Scanner scn = new Scanner(System.in);

// Solicitar al usuario el número de filas
System.out.print("Ingrese el número de filas: ");
int filas = scn.nextInt();
// Solicitar al usuario el número de columnas
System.out.print("Ingrese el número de columnas: ");
int columnas = scn.nextInt();

// Crear matriz de double
double[][] matrizDouble = new double[filas][columnas];

// Asignar valores por teclado
System.out.println("Ingrese los valores de la matriz:");
for (int i = 0; i < filas; i++) {
  for (int j = 0; j < columnas; j++) {
    System.out.print("Ingrese el valor para la posición (" + (i + 1) + ", " + (j + 1) + "): ");
    matrizDouble[i][j] = scn.nextDouble();
  }
}

// Imprimir la matriz
System.out.println();
System.out.println("Matriz resultante:");
imprimirMatrizDouble(matrizDouble);
Ingrese el número de filas: 3
Ingrese el número de columnas: 3
Ingrese los valores de la matriz:
Ingrese el valor para la posición (1, 1): 1.1
Ingrese el valor para la posición (1, 2): 2.2
Ingrese el valor para la posición (1, 3): 3.3
Ingrese el valor para la posición (2, 1): -5.66
Ingrese el valor para la posición (2, 2): -0.45
Ingrese el valor para la posición (2, 3): -12.45
Ingrese el valor para la posición (3, 1): 0
Ingrese el valor para la posición (3, 2): 9.9
Ingrese el valor para la posición (3, 3): 10.10

Matriz resultante:
1.100     2.200     3.300     
-5.660    -0.450    -12.450   
0.000     9.900     10.100    

Ejemplo 4

Dada la siguiente matriz enterosAleatorios de numeros enteros aleatorios calcula el promedio de los números pares e impares. Tambien imprime la cantidad de cada uno.

Random rand = new Random();

int filas = 4;
int columnas = 3;

// Declaración y creación
int[][] enterosAleatorios = new int[filas][columnas];

// Asignar valores
for (int i = 0; i < filas; i++) {
  for (int j = 0; j < columnas; j++) {
    // Números aleatorios entre 0 y 99
    enterosAleatorios[i][j] = rand.nextInt(100);
  }
}

System.out.println();
System.out.println("Matriz de entero aleatorios:");
imprimirMatrizInt(enterosAleatorios);

// Promedio pares e impares
int cantidadPares = 0, cantidadImpares = 0;
int sumaPares = 0, sumaImpares = 0;

for (int i = 0; i < filas; i++) {
  for (int j = 0; j < columnas; j++) {
    if (enterosAleatorios[i][j] % 2 == 0) {
      cantidadPares++;
      sumaPares += enterosAleatorios[i][j];
    } else {
      cantidadImpares++;
      sumaImpares += enterosAleatorios[i][j];
    }
  }
}

double promedioPares = (double) sumaPares/cantidadPares;
double promedioImpares = (double) sumaImpares/cantidadImpares;

System.out.println();
System.out.println("Cantidad números Pares: " + cantidadPares);
System.out.println("Promedio de números Pares: " + promedioPares);
System.out.println("Cantidad números Impares: " + cantidadImpares);
System.out.println("Promedio de números Impares: " + promedioImpares);
Matriz de entero aleatorios:
86        11        27        
1         4         46        
35        27        34        
95        3         86        

Cantidad números Pares: 5
Promedio de números Pares: 51.2
Cantidad números Impares: 7
Promedio de números Impares: 28.428571428571427

Ejemplo 5

Pide por teclado el numero de filas y columnas, crea una matriz de Strings con nombres y asigna los valores por teclado nuevamente.

Recorre los valores de la matriz, reemplaza las vocales por asteriscos e imprime cuantas vocales tiene cada nombre.

Utiliza las funciones creadas anteriormente para imprimir la matriz resultante.

Scanner scn = new Scanner(System.in);

// Solicitar al usuario el número de filas y columnas
System.out.print("Ingrese el número de filas: ");
int filas = scn.nextInt();
System.out.print("Ingrese el número de columnas: ");
int columnas = scn.nextInt();

// Crear matriz de Strings
String[][] nombres = new String[filas][columnas];

// Asignar valores
System.out.println();
System.out.println("Ingrese los valores de la matriz de Strings:");
for (int i = 0; i < filas; i++) {
  for (int j = 0; j < columnas; j++) {
    System.out.print("Ingrese el valor para la posición (" + (i + 1) + ", " + (j + 1) + "): ");
    nombres[i][j] = scn.next();
  }
}

// Matriz resultante
System.out.println();
imprimirMatrizString(nombres);
System.out.println();

// Buscar y reemplazar vocales
for (int i = 0; i < filas; i++) {
  for (int j = 0; j < columnas; j++) {
    // For para recorrer letras del nombre
    int contadorVocales = 0;
    for (char caracter: nombres[i][j].toLowerCase().toCharArray()) {
      // Si la expresión "aeiou".indexOf(caracter) es diferente de -1 signigica que es una vocal
      // .indexOf() busca cualquier coincidencia de el string a la izquierda del punto con el argumento que recibe
      if ("aeiou".indexOf(caracter) != -1) {
        contadorVocales++;
      }
    }
    System.out.println("El nombre " + nombres[i][j] + " tiene " + contadorVocales + " vocales.");

    // Remplazar vocales por *
    nombres[i][j] = nombres[i][j].replaceAll("[aeiouAEIOU]", "*");
  }
}

// Matriz Final
System.out.println();
imprimirMatrizString(nombres);
Ingrese el número de filas: 2
Ingrese el número de columnas: 3

Ingrese los valores de la matriz de Strings:
Ingrese el valor para la posición (1, 1): Juan
Ingrese el valor para la posición (1, 2): Pedro
Ingrese el valor para la posición (1, 3): Maria
Ingrese el valor para la posición (2, 1): Pablo
Ingrese el valor para la posición (2, 2): Ana
Ingrese el valor para la posición (2, 3): Sara

Juan      Pedro     Maria     
Pablo     Ana       Sara      

El nombre Juan tiene 2 vocales.
El nombre Pedro tiene 2 vocales.
El nombre Maria tiene 3 vocales.
El nombre Pablo tiene 2 vocales.
El nombre Ana tiene 2 vocales.
El nombre Sara tiene 2 vocales.

J**n      P*dr*     M*r**     
P*bl*     *n*       S*r*      

Ejemplo 6

Dada la siguiente matriz cuadrada matrizA de enteros, cambie los valores de las diagonales (principal y secundaria) por ceros.

image.png

int[][] matrizA = {
              {1, 2, 3, 4, 5},
              {6, 7, 8, 9, 10},
              {11, 12, 23, 14, 35},
              {11, 22, 33, 44, 55},
              {66, 87, 88, 89, 10}
            };

System.out.println();
System.out.println("Matriz original:");
imprimirMatrizInt(A);

int fils = matrizA.length;
int cols = matrizA[0].length;

// Cambiar valores
for (int i = 0; i < fils; i++) {
  for (int j = 0; j < cols; j++) {
    if (i == j) {
      matrizA[i][j] = 0;
    }
    matrizA[i][cols - 1 - i] = 0;
  }
}

System.out.println();
System.out.println("Matriz modificada:");
imprimirMatrizInt(A);
Matriz original:
0         2         3         4         0         
6         0         8         0         10        
11        12        0         14        35        
11        0         33        0         55        
0         87        88        89        0         

Matriz modificada:
0         2         3         4         0         
6         0         8         0         10        
11        12        0         14        35        
11        0         33        0         55        
0         87        88        89        0         

Ejemplo 7

Realiza un programa donde el usuario deba ingresar las notas y porcentaje de la nota de \(X\) estudiantes en una matriz de tipo double. El programa debe imprimir el promedio de sus calificaciones.

El número de filas corresponde a la cantidad de estudiantes y el número de columnas corresponden a las notas.

El usuario debe ingresar la nota y luego el porcentaje de dicha nota (por el momento no se valida si el total de porcentaje es mayor a \(100\%\) o si hay números negativos o fuera de rango).

Ejemplo:

Si el usuario definió que quiere ingresar 3 notas para 4 estudiantes la matriz debe tener la siguiente forma:

            Nota_1  %N1    Nota_2  %N2    Nota_3  %N3
Estud. 1     4.5     30     2.5     30     5.0     40
Estud. 2     1.5     20     3.5     25     2.1     55
Estud. 3     4.75    25     4.25    25     3.4     50
Estud. 4     2.5     35     4.1     45     2.9     20
Scanner scn = new Scanner(System.in);
Scanner scnDouble = new Scanner(System.in);

// Solicitar al usuario el número de estudiantes y notas
System.out.print("Ingrese el número de estudiantes: ");
int filas = scn.nextInt();
System.out.print("Ingrese el número de notas: ");
int columnas = scn.nextInt();
columnas *= 2;

// Crear matriz de tipo double
double[][] notasEstudiantes = new double[filas][columnas];

// Asignar valores
System.out.println();
for (int i = 0; i < filas; i++) {
  System.out.println("Estudiante " + (i+1) + ":");
  int contador = 1;
  for (int j = 0; j < columnas; j++) {
    if (j == 0) {
      System.out.print("Ingrese la nota 1: ");
    } else if (j % 2 == 0) {
      System.out.print("Ingrese la nota " + (contador) + ": ");
    } else {
      System.out.print("Ingrese el porcentaje de la nota " + (contador) + ": ");
      contador++;
    }
    notasEstudiantes[i][j] = scnDouble.nextDouble();
  }
}

System.out.println();
System.out.println("Matriz de notas:");
imprimirMatrizDouble(notasEstudiantes);

// Calcular promedio
System.out.println();
for (int i = 0; i < filas; i++) {
  double promedio = 0;
  int posPorcentaje = 1;
  for (int j = 0; j < columnas; j+=2) {
    promedio += (notasEstudiantes[i][j] * (notasEstudiantes[i][posPorcentaje]/100));
    posPorcentaje+=2;
  }
  System.out.println("Promedio estudiante " + (i+1) + ": " + promedio);
}
Ingrese el número de estudiantes: 2
Ingrese el número de notas: 3
6

Estudiante 1:
Ingrese la nota 1: 4.5
Ingrese el porcentaje de la nota 1: 30
Ingrese la nota 2: 2.5
Ingrese el porcentaje de la nota 2: 30
Ingrese la nota 3: 5.0
Ingrese el porcentaje de la nota 3: 40
Estudiante 2:
Ingrese la nota 1: 1.5
Ingrese el porcentaje de la nota 1: 20
Ingrese la nota 2: 3.5
Ingrese el porcentaje de la nota 2: 20
Ingrese la nota 3: 2.1
Ingrese el porcentaje de la nota 3: 60

Matriz de notas:
4.500     30.000    2.500     30.000    5.000     40.000    
1.500     20.000    3.500     20.000    2.100     60.000    

Promedio estudiante 1:4.1
Promedio estudiante 2:2.26

Ejemplo 8

Como se vio en clase un ejemplo practico de matrices que vemos todos los dias son las imagenes. Las imagenes a color tiene tres dimensiones y las imagenes en escala de grises o blanco y negro tienen dos dimensiones:

image.png

En el procesamiento de imagenes es común visualizar un histograma de valores de pixel, es decir, mostrar cuantas veces se repite determinado valor de pixel:

  • El eje \(X\) representa los posible valores de los pixeles \((0\) a \(255)\) y el eje \(Y\) la cantidad de veces que aparecen (depende del tamaño de la imagén).

Cargar y Procesar Imagén

Nota. Para visualizar la imagén dirigete a Archivos (carpeta al lazo izquierdo del notebook) y da doble click en el archivo Grayscale_Lena.png

// Librerias necesarias
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.io.File;
// Leer la imagen
File file = new File("Grayscale_Lena.png");
BufferedImage imageLena = ImageIO.read(file);

// Filas y Columnas
int filas = imageLena.getHeight();
int columnas = imageLena.getWidth();

System.out.println("Numero de filas: " + filas);
System.out.println("Numero de columnas: " + columnas);
Numero de filas: 256
Numero de columnas: 256
// Funciones utiles //

// Guardar imagen
private static void guardarImagen(String filePath, int[][] pixelData) throws IOException {
  int cols = pixelData[0].length;
  int fils = pixelData.length;

  // Crear un BufferedImage con el tamaño especificado
  BufferedImage image = new BufferedImage(cols, fils, BufferedImage.TYPE_BYTE_GRAY);

  // Rellenar el BufferedImage con los valores de la matriz de enteros
  for (int i = 0; i < fils; i++) {
    for (int j = 0; j < cols; j++) {
      int grayValue = pixelData[i][j];
      image.getRaster().setSample(i, j, 0, grayValue);
    }
  }

  // Crear un archivo File con la ruta especificada
  File outputFile = new File(filePath);

  // Guardar el BufferedImage como un archivo PNG
  ImageIO.write(image, "png", outputFile);
}


// Crear copia de imágen
public static int[][] copiarImagen(int[][] image) {
  int filas = image.length;
  int columnas = image[0].length;

  int[][] newImage = new int[filas][columnas];

  for(int i = 0; i < filas; i++) {
    for(int j = 0; j < columnas; j++) {
      newImage[i][j] = image[i][j];
    }
  }

  return newImage;
}


// Convertir un tipo BufferedImage a matriz de enteros bidimensional
public static int[][] procesarImagen(BufferedImage image) {

  int filas = image.getHeight();
  int columnas = image.getWidth();

  int[][] imageMatrix = new int[filas][columnas];

  for(int i = 0; i < filas; i++) {
    for(int j = 0; j < columnas; j++) {
      //imageMatrix[i][j] = image.getRaster().getSample(i, j, 0);
      imageMatrix[i][j] = image.getRGB(i, j) & 0xFF;
    }
  }

  return imageMatrix;
}

Histograma de Frecuencia

Realiza una función que reciba como parametro una imagen y devuelva un arreglo.

Pista. Cada indice del arreglo corresponderá a los valores de los pixeles (0 a 255), por lo tanto solo debes aumentar el valor de cada indice en 1.

// Convertir imagen
int[][] image = procesarImagen(imageLena);
public static int[] calcularHistograma(int[][] matriz) {
  // Crear un arreglo para almacenar el histograma
  int[] histograma = new int[256];

  // Recorrer la matriz y contar la frecuencia de cada valor
  for (int i = 0; i < matriz.length; i++) {
    for (int j = 0; j < matriz[i].length; j++) {
      int valorPixel = matriz[i][j];
      histograma[valorPixel]++;
    }
  }

  return histograma;
}

//// Calcular y mostrar Histograma ////

int[] histograma = calcularHistograma(image);

// Imprimir el histograma
for (int i = 0; i < histograma.length; i++) {
  System.out.println("Frecuencia de " + i + ": " + histograma[i]);
}
Frecuencia de 0: 0
Frecuencia de 1: 0
Frecuencia de 2: 0
Frecuencia de 3: 0
Frecuencia de 4: 1
Frecuencia de 5: 0
Frecuencia de 6: 0
Frecuencia de 7: 0
Frecuencia de 8: 1
Frecuencia de 9: 0
Frecuencia de 10: 4
Frecuencia de 11: 0
Frecuencia de 12: 2
Frecuencia de 13: 0
Frecuencia de 14: 6
Frecuencia de 15: 0
Frecuencia de 16: 6
Frecuencia de 17: 0
Frecuencia de 18: 6
Frecuencia de 19: 0
Frecuencia de 20: 7
Frecuencia de 21: 0
Frecuencia de 22: 8
Frecuencia de 23: 0
Frecuencia de 24: 11
Frecuencia de 25: 0
Frecuencia de 26: 21
Frecuencia de 27: 0
Frecuencia de 28: 45
Frecuencia de 29: 0
Frecuencia de 30: 90
Frecuencia de 31: 0
Frecuencia de 32: 124
Frecuencia de 33: 0
Frecuencia de 34: 201
Frecuencia de 35: 0
Frecuencia de 36: 294
Frecuencia de 37: 0
Frecuencia de 38: 453
Frecuencia de 39: 0
Frecuencia de 40: 630
Frecuencia de 41: 0
Frecuencia de 42: 819
Frecuencia de 43: 0
Frecuencia de 44: 935
Frecuencia de 45: 0
Frecuencia de 46: 998
Frecuencia de 47: 0
Frecuencia de 48: 1021
Frecuencia de 49: 0
Frecuencia de 50: 1017
Frecuencia de 51: 0
Frecuencia de 52: 941
Frecuencia de 53: 0
Frecuencia de 54: 827
Frecuencia de 55: 0
Frecuencia de 56: 731
Frecuencia de 57: 0
Frecuencia de 58: 677
Frecuencia de 59: 0
Frecuencia de 60: 523
Frecuencia de 61: 0
Frecuencia de 62: 450
Frecuencia de 63: 0
Frecuencia de 64: 432
Frecuencia de 65: 0
Frecuencia de 66: 427
Frecuencia de 67: 0
Frecuencia de 68: 371
Frecuencia de 69: 0
Frecuencia de 70: 357
Frecuencia de 71: 0
Frecuencia de 72: 421
Frecuencia de 73: 0
Frecuencia de 74: 443
Frecuencia de 75: 0
Frecuencia de 76: 412
Frecuencia de 77: 0
Frecuencia de 78: 451
Frecuencia de 79: 0
Frecuencia de 80: 464
Frecuencia de 81: 0
Frecuencia de 82: 428
Frecuencia de 83: 0
Frecuencia de 84: 447
Frecuencia de 85: 0
Frecuencia de 86: 467
Frecuencia de 87: 0
Frecuencia de 88: 565
Frecuencia de 89: 0
Frecuencia de 90: 567
Frecuencia de 91: 0
Frecuencia de 92: 640
Frecuencia de 93: 0
Frecuencia de 94: 706
Frecuencia de 95: 0
Frecuencia de 96: 781
Frecuencia de 97: 0
Frecuencia de 98: 994
Frecuencia de 99: 0
Frecuencia de 100: 982
Frecuencia de 101: 0
Frecuencia de 102: 940
Frecuencia de 103: 0
Frecuencia de 104: 876
Frecuencia de 105: 0
Frecuencia de 106: 731
Frecuencia de 107: 0
Frecuencia de 108: 688
Frecuencia de 109: 0
Frecuencia de 110: 666
Frecuencia de 111: 0
Frecuencia de 112: 672
Frecuencia de 113: 0
Frecuencia de 114: 714
Frecuencia de 115: 0
Frecuencia de 116: 680
Frecuencia de 117: 0
Frecuencia de 118: 777
Frecuencia de 119: 0
Frecuencia de 120: 783
Frecuencia de 121: 0
Frecuencia de 122: 921
Frecuencia de 123: 0
Frecuencia de 124: 1040
Frecuencia de 125: 0
Frecuencia de 126: 1137
Frecuencia de 127: 0
Frecuencia de 128: 0
Frecuencia de 129: 1807
Frecuencia de 130: 0
Frecuencia de 131: 1114
Frecuencia de 132: 0
Frecuencia de 133: 1004
Frecuencia de 134: 0
Frecuencia de 135: 969
Frecuencia de 136: 0
Frecuencia de 137: 954
Frecuencia de 138: 0
Frecuencia de 139: 1126
Frecuencia de 140: 0
Frecuencia de 141: 1172
Frecuencia de 142: 0
Frecuencia de 143: 1223
Frecuencia de 144: 0
Frecuencia de 145: 1158
Frecuencia de 146: 0
Frecuencia de 147: 1155
Frecuencia de 148: 0
Frecuencia de 149: 1096
Frecuencia de 150: 0
Frecuencia de 151: 1222
Frecuencia de 152: 0
Frecuencia de 153: 1284
Frecuencia de 154: 0
Frecuencia de 155: 1397
Frecuencia de 156: 0
Frecuencia de 157: 1229
Frecuencia de 158: 0
Frecuencia de 159: 1083
Frecuencia de 160: 0
Frecuencia de 161: 920
Frecuencia de 162: 0
Frecuencia de 163: 749
Frecuencia de 164: 0
Frecuencia de 165: 688
Frecuencia de 166: 0
Frecuencia de 167: 648
Frecuencia de 168: 0
Frecuencia de 169: 595
Frecuencia de 170: 0
Frecuencia de 171: 629
Frecuencia de 172: 0
Frecuencia de 173: 608
Frecuencia de 174: 0
Frecuencia de 175: 596
Frecuencia de 176: 0
Frecuencia de 177: 577
Frecuencia de 178: 0
Frecuencia de 179: 480
Frecuencia de 180: 0
Frecuencia de 181: 398
Frecuencia de 182: 0
Frecuencia de 183: 343
Frecuencia de 184: 0
Frecuencia de 185: 322
Frecuencia de 186: 0
Frecuencia de 187: 322
Frecuencia de 188: 0
Frecuencia de 189: 348
Frecuencia de 190: 0
Frecuencia de 191: 395
Frecuencia de 192: 0
Frecuencia de 193: 457
Frecuencia de 194: 0
Frecuencia de 195: 457
Frecuencia de 196: 0
Frecuencia de 197: 460
Frecuencia de 198: 0
Frecuencia de 199: 413
Frecuencia de 200: 0
Frecuencia de 201: 433
Frecuencia de 202: 0
Frecuencia de 203: 455
Frecuencia de 204: 0
Frecuencia de 205: 490
Frecuencia de 206: 0
Frecuencia de 207: 513
Frecuencia de 208: 0
Frecuencia de 209: 546
Frecuencia de 210: 0
Frecuencia de 211: 493
Frecuencia de 212: 0
Frecuencia de 213: 396
Frecuencia de 214: 0
Frecuencia de 215: 293
Frecuencia de 216: 0
Frecuencia de 217: 193
Frecuencia de 218: 0
Frecuencia de 219: 143
Frecuencia de 220: 0
Frecuencia de 221: 109
Frecuencia de 222: 0
Frecuencia de 223: 94
Frecuencia de 224: 0
Frecuencia de 225: 61
Frecuencia de 226: 0
Frecuencia de 227: 38
Frecuencia de 228: 0
Frecuencia de 229: 18
Frecuencia de 230: 0
Frecuencia de 231: 12
Frecuencia de 232: 0
Frecuencia de 233: 7
Frecuencia de 234: 0
Frecuencia de 235: 7
Frecuencia de 236: 0
Frecuencia de 237: 1
Frecuencia de 238: 0
Frecuencia de 239: 2
Frecuencia de 240: 0
Frecuencia de 241: 0
Frecuencia de 242: 0
Frecuencia de 243: 0
Frecuencia de 244: 0
Frecuencia de 245: 2
Frecuencia de 246: 0
Frecuencia de 247: 1
Frecuencia de 248: 0
Frecuencia de 249: 0
Frecuencia de 250: 0
Frecuencia de 251: 0
Frecuencia de 252: 0
Frecuencia de 253: 0
Frecuencia de 254: 0
Frecuencia de 255: 2

Modificación de Imagen

Ahora realicemos un mancha negra en la imagen

// Crear copia
int[][] imagenMod1 = copiarImagen(image);

// Recorrer la matriz
for (int i = 100; i < 150; i++) {
  for (int j = 100; j < 150; j++) {
    // El valor 0 significa negro
    imagenMod1[i][j] = 0;
  }
}

guardarImagen("Lena_Mod_1.png", imagenMod1);

La imagen anterior quedó con demasiados pixels oscuros, veamos cómo se puede arreglar un poco:

// Crear copia
int[][] imagenMod2 = copiarImagen(imagenMod1);

// Recorrer la matriz
for (int i = 0; i < imagenMod2.length; i++) {
  for (int j = 0; j < imagenMod2[i].length; j++) {
    // Si el valor del pixel + un valor X no supera los 255 entonces se suma
    if (imagenMod2[i][j] <= 220) {
      imagenMod2[i][j] += 30;
    }
  }
}

guardarImagen("Lena_Mod_2.png", imagenMod2);

Intenta restuarar la imagen original (quita la mancha negra que está en la imagen), recuerda que el nombre de la imagen sin modifica es image

Ahora apliquemos un “filtro” para que la imagen sea vea borrosa/desplazada. Para esto se debe hacer un desplazamiento y superposición.

int shift  =5;

int valor1 = 0, valor2 = 0;
int[][] imgResultado = new int[256][256];

for (int i = 0; i < 255; i++) {
  for (int j = shift; j < 255; j++) {
    // Pixel de la imagen original
    valor1 = image[i][j];

    // Pixel de la imagen desplazada
    valor2 = image[i][j-shift];

    // Promedio de los colores
    imgResultado[i][j] = (valor1 + valor2) / 2;
  }
}

guardarImagen("Lena_Mod_3.png", imgResultado);

Kernel y Convolución

«En el procesamiento de imágenes, un kernel, matriz de convolución o máscara es una pequeña matriz que se utiliza para desenfocar, enfocar, grabar, detectar bordes y más. Esto se logra haciendo una convolución entre el kernel y una imagen»

image.png

Algunos enlaces de interes:

Ejercicios#

  1. Realice una función que reciba una matriz cuadrada y devuelva la misma matriz pero girada \(90^\circ\) en sentido horario

    1, 2, 3         9, 8, 7
    4, 5, 6    =>   6, 5, 4
    7, 8, 9         3, 2, 1
  • Ahora modifica la función para que reciba el número de veces que desea girar la matriz.

  1. Realice una función que reciba dos matrices cuadradas y devuelva la suma de estas dos.

  1. Realice una función que dada una matriz (no tiene que ser cuadrada) devuelva su matriz transpuesta: