Saltar al contenido principal

Transformaciones geométricas

info

Todo el código de ejemplo se encuentra en Google Colab para su ejecución directa. Si no puedes ejecutar OpenCV localmente, puedes usar Google Colab junto con matplotlib para visualizar imágenes. Además las imágenes que se utilizarán en los ejemplos son imagen1.jpg, imagen2.jpg y sudoku.jpg.

Objetivo

  • Aprender las principales transformaciones geométricas aplicadas a imágenes.
  • Comprender cómo se modifican posición, tamaño y orientación de las imágenes.
  • Aplicar escalado, traslación, rotación, transformaciones afines y de perspectiva en OpenCV.

Conceptos clave

  • Transformación geométrica: modificación de la posición, tamaño u orientación de los píxeles de una imagen.
  • Matriz de transformación: representación matemática que define cómo se mapean los puntos de la imagen original hacia la transformada.
  • Afín: transformación que mantiene líneas rectas y paralelismo (pero no necesariamente las distancias o ángulos).
  • Perspectiva: transformación que simula la proyección en 3D, permitiendo ver la imagen como si cambiara el punto de vista.

Funciones principales en OpenCV

  • cv.resize(): Escalar imágenes.
  • cv.warpAffine(): Aplicar traslaciones, rotaciones y transformaciones afines.
  • cv.getRotationMatrix2D(): Crear la matriz de rotación.
  • cv.getAffineTransform(): Calcular la matriz afín a partir de puntos.
  • cv.getPerspectiveTransform(): Calcular la matriz de perspectiva.
  • cv.warpPerspective(): Aplicar transformación de perspectiva.

Escalar

El escalado cambia el tamaño de la imagen, ya sea reduciéndola o ampliándola. Se utiliza en preprocesamiento, para ajustar imágenes a una resolución fija o para crear miniaturas.

import cv2 as cv

img1 = cv.imread('imagen1.jpg')

# Obtener alto y ancho de la imagen original
height, width = img1.shape[:2]
print(f'Ancho: {width}, Alto: {height}')

# Redimensionar la imagen a la mitad de su tamaño original
# Usamos interpolación cúbica para mejorar la calidad en la reducción
img_resize = cv.resize(img1, (width//2, height//2), interpolation=cv.INTER_CUBIC)
print(f'Nuevo ancho: {img_resize.shape[1]}, Nuevo alto: {img_resize.shape[0]}')

cv.imshow('Imagen original', img1)
cv.imshow('Imagen escalada', img_resize)
cv.waitKey(0)
cv.destroyAllWindows()

Traslación

La traslación desplaza la imagen en el plano (horizontal o verticalmente). Se usa para reposicionar imágenes o simular movimiento.

import cv2 as cv
import numpy as np

img1 = cv.imread('imagen2.jpg', cv.IMREAD_GRAYSCALE)

# Obtener dimensiones de la imagen (filas y columnas)
rows, cols = img1.shape

# Definir la matriz de traslación (desplaza 100 píxeles en x y 50 píxeles en y)
M = np.float32([[1, 0, 100], [0, 1, 50]])

# Aplicar la traslación a la imagen usando la matriz M
dst = cv.warpAffine(img1, M, (cols, rows))

cv.imshow('Imagen original', img1)
cv.imshow('Imagen con traslacion', dst)
cv.waitKey(0)
cv.destroyAllWindows()

Rotación

La rotación gira la imagen alrededor de un punto (comúnmente su centro). Se utiliza en ajustes de orientación, aumentación de datos y corrección de inclinación.

import cv2 as cv
import numpy as np

img1 = cv.imread('imagen2.jpg', cv.IMREAD_GRAYSCALE)

# Obtener dimensiones de la imagen (filas y columnas)
rows, cols = img1.shape

# Calcular centro de la imagen
center_x, center_y = (cols-1)/2, (rows-1)/2

# Definir la matriz de rotación:
# - Centro de la imagen
# - Ángulo de rotación: 90 grados
# - Escala: 1 (mantener tamaño original)
M = cv.getRotationMatrix2D((center_x, center_y), 90, 1)

# Aplicar la rotación a la imagen usando la matriz M
dst = cv.warpAffine(img1,M,(cols,rows))

cv.imshow('Imagen original', img1)
cv.imshow('Imagen con rotacion', dst)
cv.waitKey(0)
cv.destroyAllWindows()

Transformación afín

Una transformación afín preserva las líneas rectas y el paralelismo, pero puede modificar tamaños, ángulos y formas. Se usa para cambios de perspectiva parcial o alineamiento de imágenes.

import cv2 as cv
import numpy as np

img1 = cv.imread('sudoku.jpg')

# Obtener dimensiones de la imagen (filas, columnas, canales de color)
rows, cols, _ = img1.shape

# Definir 3 puntos de la imagen original (coordenadas origen)
pts1 = np.float32([[50,50],[200,50],[50,200]])

# Definir a dónde se moverán esos 3 puntos (coordenadas destino)
pts2 = np.float32([[10,100],[200,50],[100,250]])

# Calcular la matriz de transformación afín (2x3) a partir de los 3 puntos
M = cv.getAffineTransform(pts1,pts2)

# Aplicar la transformación afín a la imagen
dst = cv.warpAffine(img1,M,(cols,rows))

cv.imshow('Imagen original', img1)
cv.imshow('Imagen con transformacion afin', dst)
cv.waitKey(0)
cv.destroyAllWindows()

Transformación de perspectiva

La transformación de perspectiva permite ver una imagen como si estuviera tomada desde otro ángulo de vista. Se usa para rectificar imágenes (por ejemplo, enderezar documentos o corregir fotografías de planos en 2D).

import cv2 as cv
import numpy as np

img1 = cv.imread('sudoku.jpg')

# Obtener dimensiones de la imagen (filas, columnas, canales de color)
rows, cols, _ = img1.shape

# Definir 4 puntos de la imagen original (coordenadas origen)
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])

# Definir a dónde se moverán esos 4 puntos (coordenadas destino)
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])

# Calcular la matriz de transformación de perspectiva (3x3) a partir de los 4 puntos
M = cv.getPerspectiveTransform(pts1,pts2)

# Aplicar la transformación de perspectiva a la imagen
dst = cv.warpPerspective(img1,M,(300,300))

cv.imshow('Imagen original', img1)
cv.imshow('Imagen con transformacion de perspectiva', dst)
cv.waitKey(0)
cv.destroyAllWindows()