PDI+VC · Exercício de Programação

EP05_05 — 🏆 Pipeline JPEG Completo: DCT, Quantização e Reconstrução

5.13.5 EP05_05 🏆 Pipeline JPEG Completo: DCT, Quantização e Reconstrução

Você foi contratado para criar, do zero, um codec JPEG didático em ambiente embarcado, sem qualquer biblioteca de imagem disponível — apenas operações matemáticas básicas. O cliente quer entender exatamente onde a qualidade é perdida e onde ela é recuperada, bloco por bloco. Este é o desafio final do capítulo: integrar tudo o que foi estudado — a DCT-II ortonormal, a quantização perceptual e a reconstrução via IDCT — em um único pipeline de ponta a ponta, processando um bloco \(N \times N\) do início ao fim, exatamente como o padrão JPEG faz internamente, \(8\times8\) pixels de cada vez.

5.13.5.1 📋 Diretrizes de Implementação

  1. Dimensão do bloco: Ler o inteiro \(N\).
  2. Bloco original: Ler a matriz de pixels \(f(x,y)\), \(N\) linhas com \(N\) inteiros em \([0,255]\).
  3. Tabela de quantização: Ler a matriz \(Q\), \(N \times N\) inteiros positivos.
  4. Centralização: Subtrair 128 de cada pixel: \(g(x,y) = f(x,y) - 128\).
  5. DCT-II 2D ortonormal: Calcular \[ 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] \] com \(\alpha(0)=\sqrt{1/N}\) e \(\alpha(k)=\sqrt{2/N}\) para \(k>0\).
  6. Quantização: \(\tilde{C}(u,v) = \text{round}(C(u,v)/Q(u,v))\).
  7. Desquantização: \(C'(u,v) = \tilde{C}(u,v)\times Q(u,v)\).
  8. IDCT-II 2D (inversa ortonormal): Calcular \(g'(x,y)\) a partir de \(C'(u,v)\) usando a transformada inversa correspondente (mesma base, somatório sobre \(u,v\)).
  9. Reversão da centralização e arredondamento: \(f'(x,y) = \text{round}(g'(x,y) + 128)\), restrito ao intervalo \([0,255]\) (clipping).
  10. Saída: Exibir o bloco reconstruído \(f'\), \(N \times N\), inteiros.

5.13.5.2 📌 Restrições Computacionais

  • Pipeline completo obrigatório: todas as seis etapas (centralizar, DCT, quantizar, desquantizar, IDCT, reverter) devem ser implementadas — pular a quantização não passa nos testes, pois o resultado seria idêntico ao original.
  • Clipping: valores reconstruídos fora de \([0,255]\) devem ser truncados (0 se negativo, 255 se maior que 255).
  • Arredondamento: tanto na quantização quanto na reconstrução final dos pixels, use arredondamento padrão; os casos de teste evitam ambiguidade .5.
  • Base ortonormal: a normalização \(\alpha(u)\) e \(\alpha(v)\) deve ser aplicada exatamente como especificado — sem ela, a IDCT não reconstrói corretamente.

5.13.5.3 🧠 Fundamentação Teórica

Etapa Análoga no padrão JPEG real Onde a qualidade é perdida
Centralização Mesma — DCT assume sinal centrado em zero Nenhuma perda
DCT-II Etapa 3–4 do pipeline (Tabela 5.7) Nenhuma perda (transformação exata e reversível)
Quantização Etapa 5 — divisão por \(Q(u,v)\) Principal fonte de perda — coeficientes de alta frequência viram zero
IDCT Reconstrução final Reconstrói exatamente os coeficientes quantizados, não os originais

5.13.5.4 📦 Especificação de Entrada e Saída (VPL)

Entrada:

  • Linha 1: Inteiro \(N\).
  • \(N\) linhas seguintes: bloco original \(f(x,y)\), inteiros em \([0,255]\).
  • \(N\) linhas seguintes: tabela de quantização \(Q\), inteiros positivos.

Saída:

  • Bloco reconstruído \(f'(x,y)\), \(N \times N\), inteiros em \([0,255]\), separados por espaço.

5.13.5.5 📌 Exemplos

Entrada Saída Observação
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
Após DCT, quantização agressiva nas altas frequências (valores grandes de \(Q\) no canto inferior direito) e reconstrução via IDCT, o bloco fica próximo do original, mas não idêntico — a diferença é o custo da compressão lossy.

5.13.5.6 💡 Dica de Depuração

Se o resultado não bater, verifique nesta ordem: (1) os coeficientes DCT brutos (antes da quantização) — eles devem reconstruir o original exatamente via IDCT se você pular a etapa 6–7; (2) a tabela \(\alpha(u)\) — erro comum é aplicar \(\sqrt{2/N}\) também para \(u=0\); (3) o arredondamento da quantização, que deve ocorrer antes de multiplicar de volta por \(Q\).

🎮 Simulador EP05_05: Pipeline JPEG (Bloco 4×4) DCT → Q → IDCT
Ajuste o fator de escala de quantização e observe o bloco reconstruído se afastar (ou se aproximar) do original.
Bloco Original
Reconstruído (DCT → Q → IDCT)
–
Figura 5.36: Simulador EP05_05: Pipeline JPEG completo em bloco
%%writefile EP05_05.py
# Código Python
Writing EP05_05.py
TestSuite("EP05_05.py").run()
✔️ EP05_05.cases já existe em casos/
📋 5 caso(s) carregado(s) de casos/EP05_05.cases

🔍 Testando Python: EP05_05.py
⚠️ EP05_05.py: Arquivo sem conteúdo (menos de 3 linhas). Testes ignorados.