diciembre 15, 2021 10:00 am

Jesús

Puede que no parezca muy impresionante a priori, pero computer vision, como cualquier otra disciplina de las ciencias de la computación, se rige por los principios de simplicidad y composición

La simplicidad se refiere a que nuestros elementos, piezas o funciones han de ser lo más sencillos y compactos posibles. 

Por su parte, la composición significa que para elaborar proyectos o soluciones más complejas, podemos combinar de múltiples maneras susodichos elementos.

Piensa por un momento en la programación tradicional. 

En el fondo, todo software se compone de una serie de ciclos, condicionales y asignaciones, ensamblados de formas creativas y novedosas. No más. 

Lo mismo sucede en computer vision: Son las pequeñas operaciones como rotación, traslación, re-escalado, entre otras, las que facilitan la existencia de aplicaciones más grandes, complejas e impresionantes.

Hoy estudiaremos otra de estas operaciones básicas: Rotaciones.

Al final de este artículo habrás aprendido:

  • En qué consiste la rotación de imágenes.
  • Cómo rotar imágenes en OpenCV.

¿Estás listo? Si es así, comencemos.

¿Qué es la Rotación de Imágenes?

rotación

Rotación

Como su nombre lo indica, rotar una imagen consiste en girarla a la izquierda o a la derecha, con base en un ángulo determinado.

De manera más precisa, para rotar una imagen, necesitamos especificar los siguientes elementos:

  1. 1
    Un ángulo. Si es positivo, giraremos en sentido antihorario, mientras que si es negativo, rotaremos en sentido horario.
  2. 2
    Un punto respecto al cual rotar. Aunque típicamente este punto es el centro de la imagen, también podemos especificar cualquier otro píxel como pivote.

¡ATENTO!

Es importante mencionar que, dependiendo del ángulo de rotación, ciertas regiones de la imagen serán cortadas con el fin de respetar las dimensiones de la misma.


Veremos ejemplos de esta situación cuando ejecutemos el programa que acompaña a este artículo.

Creación del Entorno de Desarrollo con Anaconda

Empecemos echando un vistazo a la estructura del proyecto:

.
├── datasmarts
│   └── rotate.py
├── env.yml
└── mustang.jpg

Como podemos notar, se compone de un único script, datasmarts/rotate.py, que abstrae la lógica para rotar imágenes en OpenCV.

Para crear el ambiente de Anaconda, corre este comando:

conda env create -f opencv-rotation

Esta instrucción habrá creado un ambiente llamado opencv-rotation, configurado de la siguiente manera:

Puedes activar el ambiente así:

conda activate opencv-rotation

¿Cómo vamos? ¿Bien? Genial, sigamos adelante.

Rotaciones en OpenCV

Rotar una imagen es un concepto bastante sencillo de entender: Giramos la fotografía a la izquierda o la derecha, sobre un determinado eje, con base a una cantidad de grados específicos. Si deseamos rotarla a la derecha, esta cantidad será negativa; en caso contrario, para girarla en sentido antihorario, será positiva.

Abre el archivo datasmarts/rotate.py, e inserta esta línea para importar OpenCV:

Lo siguiente que haremos es definir la función auxiliar rotate(), la cual encapsula la lógica necesaria para rotar una imagen en OpenCV:

Como sucede con muchas de las transformaciones en OpenCV, necesitamos obtener una matriz de transformación para poder rotar la imagen con base a los parámetros deseados (ángulo, eje y escala), lo cual hacemos mediante la función cv2.getRotationMatrix2D().

¡ATENTO!

Uno de los parámetros que recibe la función cv2.getRotationMatrix2D() es scale, correspondiente a la escala de la imagen resultante.


En la mayoría de los casos, pasaremos 1.0, que quiere decir que mantendremos la imagen en su tamaño original.


Sin embargo, un 2.0 querría decir que el resultado sería el doble de grande y, análogamente, 0.5 haría que el resultado tuviese la mitad en tamaño del original.

Después, pasamos dicha matriz a la conocida función cv2.warpAffine().

A continuación, cargamos la imagen de prueba en memoria usando la función cv2.imread(), para luego mostrarla en la línea siguiente, gracias a cv2.imshow():

Para poder entender los efectos de la rotación de imágenes en OpenCV, exploraremos diferentes ángulos:

Después, iteraremos sobre cada ángulo definido anteriormente, usándolo para rotar la imagen con nuestra función auxiliar rotate():

Por último, suspenderemos la ejecución del programa hasta que el usuario presione cualquier tecla:

Para ejecutar el script, ubícate en la raíz del proyecto, y corre este comando:

python datasmarts/rotate.py

En pantalla veremos, en primera instancia, la imagen original:

Imagen original.

Imagen original.

Luego, veremos la misma imagen rotada 45º en sentido antihorario:

Imagen rotada 45º

Imagen rotada 45º

Después, rotada 90º en sentido horario, es decir, -90º:

Imagen rotada -90º

Imagen rotada -90º

Posteriormente, veremos la imagen volteada completamente sobre el eje horizontal, lo que se corresponde a una rotación de 180º:

Imagen rotada 180º

Imagen rotada 180º

Por último, veremos una imagen idéntica a la original, ya que al haberla rotado 720º, efectivamente lo que hicimos fue darle dos vueltas sobre su eje central, resultando en un giro efectivo de 0º:

Imagen rotada 720º

Imagen rotada 720º

Es importante mencionar que en la mayoría de los casos, al rotar la imagen, perdimos ciertas regiones, ya que el resultado ha de tener las mismas dimensiones de la imagen original.

Un ejercicio interesante sería implementar una función auxiliar que rote las imágenes preservando todos sus píxeles, para lo que tendríamos que determinar qué dimensiones debe tener la imagen resultante para poder contener a la original en su totalidad. 

¿Te animas?

Resumen

Hoy aprendimos a rotar imágenes en OpenCV. 

Esta operación tiene muchas aplicaciones en la práctica, siendo una de las más útiles data augmentation, una técnica que consiste en añadir pequeñas perturbaciones a un conjunto de imágenes, con el fin de entrenar redes neuronales más robustas, a la vez que artificialmente incrementamos el tamaño de nuestro conjunto de datos.

Concretamente, descubrimos que para poder rotar una imagen en OpenCV, necesitamos:

  1. 1
    Generar una matriz de transformación con la función cv2.getRotationMatrix2D().
  2. 2
    Pasar dicha matriz a la función cv2.warpAffine().

Así mismo, para poder rotar una imagen, tenemos que especificar estos parámetros:

  • El ángulo de rotación.
  • El pivote o eje respecto al cual rotar (típicamente, el centro de la imagen).
  • La escala del resultado; 1.0 significa que la imagen tendrá la misma escala que la original.

Finalmente, también vimos que las rotaciones, lamentablemente tienden a cortar partes de la imagen para que el resultado preserve las dimensiones de la imagen original.

¿Te animas a crear una versión de la función rotate() que no tenga esta desventaja? Puedes descargar el código de este post a continuación, e intentarlo:

Nos vemos pronto.

Sobre el Autor

Jesús Martínez es el creador de DataSmarts, un lugar para los apasionados por computer vision y machine learning. Cuando no se encuentra bloggeando, jugando con algún algoritmo o trabajando en un proyecto (muy) cool, disfruta escuchar a The Beatles, leer o viajar por carretera.

Paso 2/2: Celebra tu NUEVO EMPLEO en Machine Learning ?

A %d blogueros les gusta esto: