EDI+VA · Esercizio di Programmazione

EP05_05 — 🏆 Pipeline JPEG Completo: DCT, Quantizzazione e Ricostruzione

5.13.5 EP05_05 🏆 Pipeline JPEG Completo: DCT, Quantizzazione e Ricostruzione

Sei stato incaricato di creare, da zero, un codec JPEG didattico in un ambiente embedded, senza alcuna libreria di immagini disponibile — solo operazioni matematiche di base. Il cliente vuole capire esattamente dove la qualità viene persa e dove viene recuperata, blocco per blocco. Questa è la sfida finale del capitolo: integrare tutto ciò che è stato studiato — la DCT-II ortonormale, la quantizzazione percettiva e la ricostruzione tramite IDCT — in un unico pipeline end-to-end, elaborando un blocco \(N \times N\) dall’inizio alla fine, esattamente come fa internamente lo standard JPEG, \(8\times8\) pixel alla volta.

5.13.5.1 📋 Linee Guida di Implementazione

  1. Dimensione del blocco: Leggere il numero intero \(N\).
  2. Blocco originale: Leggere la matrice di pixel \(f(x,y)\), \(N\) righe con \(N\) interi in \([0,255]\).
  3. Tabella di quantizzazione: Leggere la matrice \(Q\), \(N \times N\) interi positivi.
  4. Centratura: Sottrarre 128 da ogni pixel: \(g(x,y) = f(x,y) - 128\).
  5. DCT-II 2D ortonormale: Calcolare \[ C(u,v) = \alpha(u)\,\alpha(v)\sum_{x=0}^{N-1}\sum_{y=0}^{N-1} g(x,y)\,\cos\!\left[\frac{\pi(2x+1)u}{2N}\right]\cos\!\left[\frac{\pi(2y+1)v}{2N}\right] \] con \(\alpha(0)=\sqrt{1/N}\) e \(\alpha(k)=\sqrt{2/N}\) per \(k>0\).
  6. Quantizzazione: \(\tilde{C}(u,v) = \text{round}(C(u,v)/Q(u,v))\).
  7. Dequantizzazione: \(C'(u,v) = \tilde{C}(u,v)\times Q(u,v)\).
  8. IDCT-II 2D (inversa ortonormale): Calcolare \(g'(x,y)\) da \(C'(u,v)\) usando la trasformata inversa corrispondente (stessa base, sommatoria su \(u,v\)).
  9. Inversione della centratura e arrotondamento: \(f'(x,y) = \text{round}(g'(x,y) + 128)\), limitato all’intervallo \([0,255]\) (clipping).
  10. Output: Visualizzare il blocco ricostruito \(f'\), \(N \times N\), interi.

5.13.5.2 📌 Vincoli Computazionali

  • Pipeline completo obbligatorio: tutte e sei le fasi (centrare, DCT, quantizzare, dequantizzare, IDCT, invertire) devono essere implementate — saltare la quantizzazione non supera i test, poiché il risultato sarebbe identico all’originale.
  • Clipping: i valori ricostruiti al di fuori di \([0,255]\) devono essere troncati (0 se negativi, 255 se maggiori di 255).
  • Arrotondamento: sia nella quantizzazione che nella ricostruzione finale dei pixel, usare l’arrotondamento standard; i casi di test evitano ambiguità .5.
  • Base ortonormale: la normalizzazione \(\alpha(u)\) e \(\alpha(v)\) deve essere applicata esattamente come specificato — senza di essa, la IDCT non ricostruisce correttamente.

5.13.5.3 🧠 Fondamenti Teorici

Fase Analoga nel vero standard JPEG Dove la qualità viene persa
Centratura Stessa — la DCT presuppone un segnale centrato su zero Nessuna perdita
DCT-II Fasi 3–4 del pipeline (Tabella 5.7) Nessuna perdita (trasformazione esatta e reversibile)
Quantizzazione Fase 5 — divisione per \(Q(u,v)\) Principale fonte di perdita — i coefficienti ad alta frequenza diventano zero
IDCT Ricostruzione finale Ricostruisce esattamente i coefficienti quantizzati, non quelli originali

5.13.5.4 📦 Specifica di Input e Output (VPL)

Input:

  • Riga 1: Intero \(N\).
  • \(N\) righe successive: blocco originale \(f(x,y)\), interi in \([0,255]\).
  • \(N\) righe successive: tabella di quantizzazione \(Q\), interi positivi.

Output:

  • Blocco ricostruito \(f'(x,y)\), \(N \times N\), interi in \([0,255]\), separati da spazi.

5.13.5.5 📌 Esempi

Input Output Osservazione
4
120 130 125 128
115 140 135 122
118 150 160 130
110 120 145 138
4 6 8 10
6 8 10 12
8 10 12 16
10 12 16 20
118 126 119 131
114 143 140 119
117 149 159 130
107 121 146 139
Dopo la DCT, una quantizzazione aggressiva sulle alte frequenze (valori grandi di \(Q\) nell’angolo in basso a destra) e la ricostruzione tramite IDCT, il blocco risulta vicino all’originale, ma non identico — la differenza è il costo della compressione lossy.

5.13.5.6 💡 Suggerimento per il Debug

Se il risultato non corrisponde, verifica in questo ordine: (1) i coefficienti DCT grezzi (prima della quantizzazione) — devono ricostruire l’originale esattamente tramite IDCT se salti le fasi 6–7; (2) la tabella \(\alpha(u)\) — un errore comune è applicare \(\sqrt{2/N}\) anche per \(u=0\); (3) l’arrotondamento della quantizzazione, che deve avvenire prima di moltiplicare di nuovo per \(Q\).

🎮 Simulatore EP05_05: Pipeline JPEG (Blocco 4×4) DCT → Q → IDCT
Regola il fattore di scala di quantizzazione e osserva il blocco ricostruito allontanarsi (o avvicinarsi) dall'originale.
Blocco Originale
Ricostruito (DCT → Q → IDCT)
–
Figura 5.36: Simulatore EP05_05: Pipeline JPEG completo a blocchi
%%writefile EP05_05.py
# Codice Python
Overwriting EP05_05.py
TestSuite("EP05_05.py").run()
✔️ EP05_05.cases esiste già in casos/
📋 5 caso/i caricato/i da casos/EP05_05.cases

🔍 Test di Python: EP05_05.py
⚠️ EP05_05.py: file vuoto (meno di 3 righe). Test saltati.