2.12.11 EP02_11 🏆 Correzione della Prospettiva (Omografia) su Immagine Reale
In questa attività, l’obiettivo è applicare la trasformazione prospettica (omografia) per “raddrizzare” un oggetto inclinato in una fotografia reale. Lavorerai con l’immagine di un giornale, dove la griglia di un gioco di Sudoku è distorta a causa dell’angolo con cui è stata scattata la foto.
Il tuo programma deve leggere i parametri di input dal terminale, caricare l’immagine, calcolare la matrice di omografia \(3 \times 3\), applicare la trasformazione geometrica e visualizzare un indicatore globale di validazione.
- Leggi due interi L e C, che rappresentano le dimensioni di righe e colonne (altezza e larghezza) che l’immagine rettificata di uscita deve avere.
- Leggi quattro coppie di coordinate \((x, y)\) dal terminale, che rappresentano i quattro angoli del quadrilatero di origine (il Sudoku distorto nell’immagine originale).
- Calcola automaticamente le quattro coppie di coordinate di destinazione utilizzando le dimensioni \(L\) e \(C\) fornite, mappando gli angoli agli estremi della nuova immagine: \((0,0)\), \((C-1, 0)\), \((0, L-1)\) e \((C-1, L-1)\).
- Carica l’immagine locale
sudoku.pnge convertila in scala di grigi (grayscale). - Calcola la matrice di omografia e applica la trasformazione spaziale all’immagine.
- Output: Calcola e stampa la somma di tutti i pixel dell’immagine risultante.
📌 Importante:
- File di input: L’immagine
sudoku.pngdeve trovarsi nella stessa cartella dello script. Il programma deve leggerla direttamente dal disco (es: usandomm.read("sudoku.png")ocv2.imread). - Ordine dei Punti: Assicurati che la lettura dei 4 punti di origine e la generazione dei 4 punti di destinazione seguano rigorosamente lo stesso ordine degli angoli: Superiore-Sinistro (TL), Superiore-Destro (TR), Inferiore-Sinistro (BL) e Inferiore-Destro (BR).
- Dimensioni in OpenCV: Ricorda che funzioni come
cv2.warpPerspectivesi aspettano la dimensione dell’immagine di uscita nel formato(larghezza, altezza), che equivale a(C, L). - Interpolazione: Per garantire la coerenza matematica della somma dei pixel con il correttore automatico, utilizza l’interpolazione bilineare standard (
flags=cv2.INTER_LINEAR). - Crediti: L’immagine utilizzata è “Sudoku en periódico” di Héctor Rodríguez, sotto licenza CC BY 2.0.
2.12.11.1 🧠 Contesto del Problema
L’omografia ha 8 gradi di libertà, richiedendo almeno 4 corrispondenze di punti per essere calcolata. A differenza delle trasformazioni affini, mappa qualsiasi quadrilatero in un altro quadrilatero, permettendo che le linee che convergono verso punti di fuga tornino ad essere parallele:
| Operazione | Caratteristica | Applicazione Tipica |
|---|---|---|
| Omografia | Proiezione tra piani | Rettifica di documenti, scansione di targhe e codici QR. |
| Mappatura Inversa | Scansione dalla destinazione all’origine | Evita “buchi” o pixel vuoti nell’immagine finale rettificata. |
| Warping | Ricampionamento spaziale | Correzione della distorsione delle lenti e montaggio di panorami (stitching). |
2.12.11.2 📌 Esempi
| Input | Output | Osservazione |
|---|---|---|
| 500 500 100 120 420 95 80 440 450 460 |
32982820 | I primi due input sono le dimensioni di uscita (\(L\) e \(C\)). Le 4 righe successive sono le coordinate \((x, y)\) degli angoli del Sudoku nell’immagine originale + PAD. L’output è la somma totale dei pixel dell’immagine rettificata. |
| 200 200 100 120 420 95 80 440 450 460 |
5277150 | Stessi punti di origine dell’esempio precedente, ma generando un’immagine di uscita più piccola (\(200 \times 200\)). La somma dei pixel si riduce proporzionalmente a causa della scala. |
2.12.11.3 Acquisizione dell’immagine del sudoku e conversione in livelli di grigio
La Figura 2.22 mostra la lettura dell’immagine originale seguita dalla conversione in tonalità di grigio e dal ridimensionamento a una matrice di \(500 \times 500\) pixel, preparando i dati per la fase successiva.
La correzione di prospettiva, applicata nella Figura 2.23 tramite matrice di omografia, elimina le deformazioni causate dall’angolo della telecamera e produce una visione frontale e regolare della griglia del Sudoku.
import cv2
import numpy as np
# --- 1. Carica l'immagine salvata (sudoku.png) ---
img = mm.read("sudoku.png") # BGR, 500×500
# --- 2. Padding per non tagliare i vertici ---
PAD = 60
img_pad = cv2.copyMakeBorder(
img, PAD, PAD, PAD, PAD,
cv2.BORDER_CONSTANT, value=[255, 255, 255]
)
# --- 3. Punti di origine (angoli della griglia nell'immagine espansa) ---
pts1 = np.float32([
[100, 160], # TL
[390, 45], # TR
[200, 580], # BL
[570, 420], # BR
])
# W H
# --- 4. Punti di destinazione (vista frontale 500×500) ---
SIZE = 500
pts2 = np.float32([
[0, 0],
[SIZE, 0],
[0, SIZE],
[SIZE, SIZE],
])
# --- 5. Omografia e raddrizzamento ---
img_rect = mm.perspective_transform(img_pad, pts1, pts2, size=(SIZE, SIZE))
# --- 6. Visualizzazione ---
mm.show(
[img_pad, img_rect],
titles=["Originale (con padding)", "Vista frontale raddrizzata"],
cols=2, figsize=(10, 6), axis=True
)
%%writefile EP02_11.py
# Codice PythonOverwriting EP02_11.py
TestSuite("EP02_11.py").run()✔️ EP02_11.cases esiste già in casos/
📋 4 caso/i caricato/i da casos/EP02_11.cases
🔍 Test di Python: EP02_11.py
⚠️ EP02_11.py: file vuoto (meno di 3 righe). Test saltati.