Manipulación de imágenes con librería openCV
La vista es uno de los sentidos más importantes, ya que proporciona mucha información sobre el mundo que puede determinar si se debe actuar o no. Por esta razón, los informáticos se han esforzado durante años en darle esta capacidad a las computadoras, pues si bien ellas ya son capaces de grabar imágenes y videos con alta fidelidad, esto no es lo mismo que ver.
Esta área de estudio se denomina Visión por Computadora y actualmente existen bibliotecas que se pueden utilizar para facilitar el trabajo con imágenes y videos como openCV con el cual trabajaremos a lo largo de este artículo.
¿Qué son imágenes y videos para una computadora?
Primero, ten en cuenta que las imágenes para una computadora son solo un conjunto de números. La unidad más pequeña de una foto se llama píxel, el cual está compuesto por tres números: uno para representar el rojo, otro el verde y otro el azul. Los valores para cada uno están entre 0 y 255. Variándolos y combinándolos podemos obtener cualquier color. También está el canal alfa, cuyo valor representa el nivel de transparencia de ese píxel.
Los videos, por otro lado, son básicamente un conjunto de imágenes colocadas una detrás de otra a las que llamamos frames. Cuando se reproducen en secuencia, dan la impresión de movimiento.
¿Qué puede hacerse con Visión por Computadora?
Existen varios proyectos interesantes que se pueden realizar a través del análisis de imágenes y videos, entre ellos se encuentran:
- Reconocimiento de objetos (classificación).
- Remoción de fondo de un video y edición de filtros (muy utilizado en aplicaciones de videollamadas).
- Rastreo de objetos.
- Generación de imágenes y videos (crear posts automáticamente para redes sociales).
- Deep fake (reemplazar el rosto de una persona en un video por otro).
- Drones inteligentes para seguir objetos o pessoas y desviarse de obstáculos.
- Rastreo de manos (para dar comandos).
- Reconocimiento facial (puede colocarse en una cámara de seguridad).
- Lector de QR y código de barras.
Se pueden utilizar diferentes técnicas para cada uno de estos proyectos. Para ubicar un objeto en una imagen, por ejemplo, basta con indicar los valores de color de los píxeles del objeto. Como un video es una secuencia de imágenes, simplemente repite el proceso para cada frame.
Pero claro, para algunos proyectos como el deep fake, será necesario utilizar algoritmos más sofisticados (como las redes neuronales) en un proceso conocido como deep learning, que consiste en utilizar varias capas de neuronas para hacer un aprendizaje profundo (de ahí el nombre).
Utilizando a biblioteca openCV
Para comenzar, usaremos el lenguaje Python como ejemplo, pero la biblioteca también está disponible en otros idiomas. Es un proyecto de código abierto, inicialmente desarrollado por Intel y hoy en día cuenta con varios algoritmos para procesamiento de imágenes, video y creación de interfaces de usuario.
Primero configuremos el entorno de desarrollo, creando un entorno virtual e instalando la biblioteca. Escribe en la terminal:
Luego, si estás usando Windows, actívalo con el siguiente comando:
Instala ahora la biblioteca:
El comando instalará automáticamente numpy, otra biblioteca que también facilita el trabajo con Visión por Computadora.
Ahora crea un archivo llamado main.py y una carpeta llamada assets y coloca una imagen dentro de ella. Luego importa las bibliotecas en el archivo main.py:
Comandos básicos para manipulación de imágenes
Para manipular las imágenes primero es necesario importarlas al código. Esto lo haremos con la función imread, donde se pasará como primer parámetro la ruta a la imagen y el segundo será un número. -1 significa sin el canal alfa, es decir, cualquier transparencia que tenga la imagen, mientras que 0 (cero) significa cargar en blanco y negro y 1 es incluir el canal alfa.
Luego es necesario llamar a la función imshow y pasar una cadena con el título y la variable con la imagen. Hecho esto, simplemente llama a la función waitKey para que el programa espere hasta que presiones cualquier tecla (pasando el número 0, esperará indefinidamente) y finalmente, llama a la función destroyAllWindows para cerrar.
Al ejecutar el programa, se abrirá una ventana con la imagen. Ahora puede, por ejemplo, manipular las dimensiones a través del comando resize, pasando la imagen y el tamaño en los ejes x e y entre paréntesis (nota: los comandos para manipular deben pasar antes que el imshow).
También es posible cambiar la dimensión a través del porcentaje, simplemente pasa 0 para los dos valores dentro de los paréntesis y luego especifica cuánto multiplicar para fx y fy. Por ejemplo, pasar 0,5 será la mitad del tamaño y 2 será el doble:
Otro cambio que puedes hacer es rotar la imagen:
Este comando rotará 90 grados en el sentido de las agujas del reloj. Ahora, para guardar los cambios, simplemente inserta la función imwrite, pasando el nombre del archivo después de la imagen:
¿Cómo las imagens son representadas?
La biblioteca openCV almacena imágenes en forma de objetos numpy. Numpy es una biblioteca que permite trabajar con arrays (listas) de una manera más optimizada. Si haces un print con el type y con frame puedes acceder al tipo y a la forma de este objeto:
Shape devolverá en una tupla (sencuancia ordenada y finita de elementos) la altura, el ancho y los canales respectivamente. Es como una tabla en Excel: una lista contendrá otras que serían las líneas, dentro de ellas habrá otras más que serían las columnas y dentro de cada columna habrá 3 valores, así:
Como decía al principio, cada píxel de la imagen está compuesto por 3 números, los famosos RGB (Rojo, Verde y Azul), pero openCV representa todo lo contrario, por lo que sería primero el azul, el verde y luego el rojo.
Para crear o modificar una imagen, lo único que se hará es modificar este estado, ya sea aumentando o disminuyendo el número de filas y columnas o variando el valor de intensidad asociado a cada color de los píxeles.
Puedes acceder al valor de cada uno individualmente como una lista en Python:
El código anterior dice que vayas a la fila 275, columna 312 y que la intensidad del verde será de 10.
Podemos crear un algoritmo para codificar los píxeles de la imagen estableciendo sus valores aleatoriamente como prueba. Primero, importa la función randint de la biblioteca aleatoria al principio del código y al final, antes de mostrar la imagen, haz un loop para acceder a las filas, luego a las columnas. Luego pasa una lista a esa ubicación en la imagen que contiene los valores de intensidad del azul, verde y rojo, pero en lugar de poner un valor fijo, usa la función randint, la cual recibirá dos parámetros que son el principio y el final:
En el primer loop, el valor se fija en 100 y en el segundo le pasamos el número total de columnas. El randint recibe el valor 255 por ser la máxima intensidad de color, al ejecutar se puede ver que las primeras 100 filas y todas las columnas se verán afectadas: cada píxel tendrá un color diferente, pero a partir del píxel 101 la imagen será normal.
Manipulación avanzada de imágenes
- Recortar y pegar: esa función consiste básicamente en tomar una parte de los valores de array numpy, pasarlos a una variable y reemplazarlos en un lugar del mismo tamaño, ya sea en la misma imagen o en otra.
- Cambiar perspectiva: cuando se obtiene una imagen de un objeto en un ángulo no muy favorable, existe una forma de cambiarla para que quede de frente. Para ello, primero indica los puntos de la imagen de interés y luego usa las funciones getPerspectiveTransform y warpPerspective. OpenCV analizará la distancia entre esos puntos, rotar y escalar los valores para cambiar la perspectiva del objeto.
- Aplicar filtros: los filtros son alteraciones en los colores de la imagen. Por ejemplo, puedes alterar la intensidad de azul o rojo de los píxeles para dar tonos más fríos o cálidos. Los filtros son aplicables en una parte o en la totalidad de la foto. También puedes usar funciones matemáticas para hacer blur, que difumina la foto.
En el código fuente de este artículo hay imágenes y ejemplos de código de cómo se pueden realizar estas funciones con openCV.
Crear imágenes con texto y formas geométricas simples
Ahora puedes crear tus propias imágenes. Para eso, genera otro archivo de Python al que podrás llamar image_generator.py e importar las bibliotecas numpy y openCV. Primero, crearemos un objeto numpy con solo ceros, para lo cual usaremos la función zeros con una tupla que contiene las dimensiones de alto, ancho y los tres colores. El segundo parámetro será el tipo de datos, que definiremos como uint8.
Al ejecutar solo verás una pantalla negra. Hecho esto, podemos crear rectángulos, círculos y polígonos para dibujar un paisaje. Primero crearemos dos rectángulos, uno para representar el cielo y el otro el suelo.
Para crear el rectángulo, el primer argumento que se inserta es la imagen, el segundo es una tupla con las coordenadas de inicio, el tercero otra tupla con las coordenadas finales, luego una tupla con la intensidad de cada color y finalmente el parámetro que define el grosor de el borde. Si este parámetro es -1 significa que es para rellenar toda la figura, pero si es un número positivo, definirás el grosor del borde, pero no se rellenará el interior.
Hecho esto, podemos crear el sol utilizando dos círculos: el primero será más pequeño y se llenará completamente de amarillo, mientras que el segundo será más grande. Definiremos el borde para que no se llene por completo y cambiaremos el tono amarillo:
A diferencia del rectángulo, en el círculo pasamos las coordenadas del centro del círculo como segundo parámetro y el tercer parámetro es el radio. Ahora podemos crear un árbol. Primero comenzaremos con el tronco, que será una línea.
El segundo parámetro es una tupla con los valores iniciales y el tercer parámetro los valores finales. Ten en cuenta que la posición x es la misma en ambos, por lo que será una línea vertical. Luego pasamos el color y finalmente el grosor de la línea.
Ahora vamos a crear las hojas, que serán triángulos verdes. Es un poco diferente a las otras figuras, así que para crearlas necesitamos hacer una matriz numpy que contenga listas que definirán las coordenadas de los vértices del triángulo.
A função fillPoly é o que vai colocar o polígono na imagem, o segundo parâmetro é o objeto triângulo numpy que criamos. Para finalizar, colocaremos um texto:
Primero seleccionamos una de las fuentes disponibles, luego vamos a la función putText, donde vamos a la imagen, el texto, las coordenadas, la fuente, la escala, el color y el grosor de la línea, respectivamente.
Para evitar la repetición de código, si deseas crear un bosque en lugar de solo un árbol, puedes usar clases y variar uno o dos parámetros para cada objeto, desde la longitud de las hojas, el tamaño, la forma, etc.
Conclusión
Con lo que has aprendido en este artículo, ya tienes las bases para empezar a manipular cualquier imagen a través de la programación. La diferencia entre lo que hemos hecho hoy y aplicaciones como Photoshop o Canva es que han creado una serie de comandos como los que hemos visto aquí y han puesto una interfaz de usuario más amigable para facilitar la creación.
Saber manipular imágenes a través de la programación te permitirá diseñar sistemas más complejos utilizando diferentes tipos de algoritmos para generar imágenes diversas, como por ejemplo las redes generativas antagónicas (Generative Adversarial Networks), que consisten en dos redes neuronales, una entrenada para crear imágenes y la otra para juzgar si una imagen fue hecha por un robot o es real.
El objetivo de la primera red es engañar a la segunda y el de la segunda es no dejarse engañar, por lo que luego de procesar una imagen se revela a ambas redes el resultado de quién ganó. El perdedor tiene que actualizar el modelo. De esta manera es posible mejorar la red que genera las imágenes, aumentando el nivel de detalle con el tiempo.
También es posible mejorar el análisis de la imagen observando píxel a píxel para identificar todos los objetos presentes en ella y combinar esto con, por ejemplo, el sistema de copiar y pegar de tu computadora para crear imágenes relacionando objetos y, junto con un algoritmo de red neuronal, empezar a contar historias y a crear proyectos complejos. Pero claro, este tipo de tecnología no se crea de la noche a la mañana. Cuando exista lo anterior, lo único que limitará tu poder de creación será tu imaginación :D
Para acceder al código fuente completo de este proyecto y las imágenes generadas, consulta el repositorio en GitHub.
¡Éxito!
Revelo Content Network da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.