Transformaciones geométricas
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
# 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]}')
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen original")
axes[1].imshow(cv.cvtColor(img_resize, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen escalada")
plt.show()
Traslación
La traslación desplaza la imagen en el plano (horizontal o verticalmente). Se usa para reposicionar imágenes o simular movimiento.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0], 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))
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
axes[0].imshow(img1, cmap="gray")
axes[0].set_title("Imagen original")
axes[0].axis("off")
axes[1].imshow(dst, cmap="gray")
axes[1].set_title("Imagen con traslacion")
axes[1].axis("off")
plt.show()
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0], 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))
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
axes[0].imshow(img1, cmap="gray")
axes[0].scatter(center_x, center_y, c="red", s=50, marker="x")
axes[0].set_title("Imagen original")
axes[1].imshow(dst, cmap="gray")
axes[1].set_title("Imagen con rotacion")
plt.show()
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
# 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))
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen original")
axes[1].imshow(cv.cvtColor(dst, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen con transformacion afin")
plt.show()
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).
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
# 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, (cols, rows))
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 2, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen original")
axes[1].imshow(cv.cvtColor(dst, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen con transformacion de perspectiva")
plt.show()