PDI+VC · Ejercicio de Programación

EP02_11 — 🏆 Corrección de Perspectiva (Homografía) en Imagen Real

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.png y 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.png debe estar en la misma carpeta que el script. El programa debe leerla directamente del disco (por ejemplo, usando mm.read("sudoku.png") o cv2.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.warpPerspective esperan 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.

Figura 2.22: Adquisición de la imagen de un Sudoku a la izquierda. A la derecha, conversión a tonos de gris y redimensionamiento. Crédito: Héctor Rodríguez de Guardamar, España (CC BY 2.0).
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
)
Figura 2.23: Corrección de perspectiva: original y vista frontal rectificada.
🎮 Simulador EP02_11: Perspectiva del Sudoku Homografía 3×3 · CC BY 2.0
📷 Original (Expandida) — Arrasta las Esquinas Foto: Héctor Rodríguez · CC BY 2.0
✅ Corregida (400×400) — Vista Frontal
Cargando imagen del Sudoku...
Figura 2.24: Simulador EP02_11: Corrección de Perspectiva del Sudoku (Homografía 3×3 con Remuestreo Bilineal)
%%writefile EP02_11.py
# Código Python
Overwriting 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.