2.12.11 EP02_11 🏆 Corrección de Perspectiva (Homografía) en Imagen Real
En esta actividad, el objetivo es aplicar la transformación de perspectiva (homografía) para “rectificar” un objeto inclinado en una fotografía real. Trabajarás con la imagen de un periódico, donde la cuadrícula de un juego de Sudoku está distorsionada debido al ángulo en que se tomó la foto.
Tu programa debe leer los parámetros de entrada desde el terminal, cargar la imagen, calcular la matriz de homografía \(3 \times 3\), aplicar la transformación geométrica y mostrar un indicador global de validación.
- Lee dos enteros L y C, que representan las dimensiones de filas y columnas (alto y ancho) que debe tener la imagen rectificada de salida.
- Lee cuatro pares de coordenadas \((x, y)\) desde el terminal, que representan las cuatro esquinas del cuadrilátero de origen (el Sudoku distorsionado en la imagen original).
- Calcula automáticamente los cuatro pares de coordenadas de destino utilizando las dimensiones \(L\) y \(C\) proporcionadas, mapeando las esquinas a los extremos de la nueva imagen: \((0,0)\), \((C-1, 0)\), \((0, L-1)\) y \((C-1, L-1)\).
- Carga la imagen local
sudoku.pngy conviértela a escala de grises. - Calcula la matriz de homografía y aplica la transformación espacial en la imagen.
- Salida: Calcula e imprime la suma de todos los píxeles de la imagen resultante.
📌 Importante:
- Archivo de entrada: La imagen
sudoku.pngdebe estar en la misma carpeta que el script. El programa debe leerla directamente del disco (por ejemplo, usandomm.read("sudoku.png")ocv2.imread). - Orden de los puntos: Asegúrate de que la lectura de los 4 puntos de origen y la generación de los 4 puntos de destino sigan rigurosamente el mismo orden de las esquinas: Superior-Izquierda (TL), Superior-Derecha (TR), Inferior-Izquierda (BL) e Inferior-Derecha (BR).
- Dimensiones en OpenCV: Recuerda que funciones como
cv2.warpPerspectiveesperan el tamaño de la imagen de salida en el formato(ancho, alto), lo que equivale a(C, L). - Interpolación: Para garantizar la consistencia matemática de la suma de píxeles con el corrector automático, utiliza la interpolación bilineal estándar (
flags=cv2.INTER_LINEAR). - Créditos: La imagen utilizada es “Sudoku en periódico” de Héctor Rodríguez, bajo licencia CC BY 2.0.
2.12.11.1 🧠 Contexto del Problema
La homografía tiene 8 grados de libertad, lo que requiere al menos 4 correspondencias de puntos para calcularse. A diferencia de las transformaciones afines, mapea cualquier cuadrilátero en otro cuadrilátero, permitiendo que las líneas que convergen en puntos de fuga vuelvan a ser paralelas:
| Operación | Característica | Aplicación Típica |
|---|---|---|
| Homografía | Proyección entre planos | Rectificación de documentos, escaneo de placas y códigos QR. |
| Mapeo Inverso | Recorrido del destino al origen | Evita “agujeros” o píxeles vacíos en la imagen final rectificada. |
| Warping | Remuestreo espacial | Corrección de distorsión de lentes y montaje de panoramas (stitching). |
2.12.11.2 📌 Ejemplos
| Entrada | Salida | Observación |
|---|---|---|
| 500 500 100 120 420 95 80 440 450 460 |
32982820 | Las dos primeras entradas son las dimensiones de salida (\(L\) y \(C\)). Las 4 líneas siguientes son las coordenadas \((x, y)\) de las esquinas del Sudoku en la imagen original + PAD. La salida es la suma total de los píxeles de la imagen rectificada. |
| 200 200 100 120 420 95 80 440 450 460 |
5277150 | Mismos puntos de origen que el ejemplo anterior, pero generando una imagen de salida más pequeña (\(200 \times 200\)). La suma de píxeles se reduce proporcionalmente debido a la escala. |
2.12.11.3 Adquisición de la imagen del sudoku y conversión a niveles de gris
La Figura 2.22 muestra la lectura de la imagen original seguida de la conversión a tonos de gris y el redimensionamiento a una matriz de \(500 \times 500\) píxeles, preparando los datos para la etapa siguiente.
La corrección de perspectiva, aplicada en la Figura 2.23 mediante la matriz de homografía, elimina las deformaciones causadas por el ángulo de la cámara y produce una vista frontal y regular de la cuadrícula del Sudoku.
import cv2
import numpy as np
# --- 1. Carga la imagen guardada (sudoku.png) ---
img = mm.read("sudoku.png") # BGR, 500×500
# --- 2. Padding para no recortar vértices ---
PAD = 60
img_pad = cv2.copyMakeBorder(
img, PAD, PAD, PAD, PAD,
cv2.BORDER_CONSTANT, value=[255, 255, 255]
)
# --- 3. Puntos de origen (esquinas de la cuadrícula en la imagen expandida) ---
pts1 = np.float32([
[100, 160], # TL
[390, 45], # TR
[200, 580], # BL
[570, 420], # BR
])
# W H
# --- 4. Puntos de destino (vista frontal 500×500) ---
SIZE = 500
pts2 = np.float32([
[0, 0],
[SIZE, 0],
[0, SIZE],
[SIZE, SIZE],
])
# --- 5. Homografía y rectificación ---
img_rect = mm.perspective_transform(img_pad, pts1, pts2, size=(SIZE, SIZE))
# --- 6. Visualización ---
mm.show(
[img_pad, img_rect],
titles=["Original (con padding)", "Vista frontal rectificada"],
cols=2, figsize=(10, 6), axis=True
)
%%writefile EP02_11.py
# Código PythonOverwriting EP02_11.py
TestSuite("EP02_11.py").run()✔️ EP02_11.cases ya existe en casos/
📋 4 caso(s) cargado(s) de casos/EP02_11.cases
🔍 Probando Python: EP02_11.py
⚠️ EP02_11.py: archivo vacío (menos de 3 líneas). Pruebas omitidas.