5.13.3 EP05_03 🟠 Quantização DCT: a Verdadeira Fonte de Compressão
Um aplicativo de galeria de fotos precisa reduzir o tamanho de milhares de imagens antes de fazer upload para a nuvem, sem recodificar tudo do zero. O engenheiro responsável já tem os coeficientes DCT de cada bloco \(4\times4\) calculados (a etapa cara computacionalmente já foi feita) — falta apenas aplicar a tabela de quantização, a etapa que realmente descarta informação e gera compressão. Coeficientes de alta frequência, menos perceptíveis ao olho humano, recebem divisores grandes e tendem a virar zero; coeficientes de baixa frequência, mais perceptíveis, recebem divisores pequenos e sobrevivem quase intactos.
Você vai implementar exatamente essa etapa: quantizar e desquantizar (dividir, arredondar, multiplicar de volta) — o coração da compressão lossy do JPEG.
5.13.3.1 📋 Diretrizes de Implementação
- Dimensão do bloco: Ler o inteiro \(N\) (bloco \(N \times N\)).
- Coeficientes: Ler a matriz \(C\) de coeficientes DCT, \(N\) linhas com \(N\) inteiros cada (podem ser negativos).
- Tabela de quantização: Ler a matriz \(Q\), \(N\) linhas com \(N\) inteiros positivos cada.
- Quantização: Para cada posição \((u,v)\), calcular o índice quantizado \[
\tilde{C}(u,v) = \text{round}\!\left(\frac{C(u,v)}{Q(u,v)}\right)
\] usando arredondamento padrão para o inteiro mais próximo (valores intermediários
.5nunca ocorrem nos casos de teste). - Desquantização (reconstrução): Calcular \[ C'(u,v) = \tilde{C}(u,v) \times Q(u,v) \]
- Saída: Exibir a matriz reconstruída \(C'\), \(N \times N\), inteiros.
5.13.3.2 📌 Restrições Computacionais
- Round-trip completo: a saída é o coeficiente reconstruído (\(\tilde{C} \times Q\)), não o índice quantizado isolado.
- Divisão em ponto flutuante: a divisão \(C(u,v)/Q(u,v)\) deve ser feita em ponto flutuante antes do arredondamento — divisão inteira truncada produzirá resultado incorreto.
- Sinal preservado: coeficientes negativos mantêm o sinal após quantização e reconstrução.
- \(Q(u,v) > 0\) sempre: não há necessidade de tratar divisão por zero.
5.13.3.3 🧠 Fundamentação Teórica
| Coeficiente | Frequência | Valor típico de \(Q\) | Efeito da quantização |
|---|---|---|---|
| \(C(0,0)\) | DC (média do bloco) | Pequeno | Quase sempre sobrevive — domina a energia |
| \(C(u,v)\) baixo \(u+v\) | Baixa frequência | Pequeno/médio | Parcialmente preservado |
| \(C(u,v)\) alto \(u+v\) | Alta frequência | Grande | Frequentemente vira zero — fonte da compressão |
5.13.3.4 📦 Especificação de Entrada e Saída (VPL)
Entrada:
- Linha 1: Inteiro \(N\).
- \(N\) linhas seguintes: matriz \(C\) (coeficientes DCT, inteiros, podem ser negativos).
- \(N\) linhas seguintes: matriz \(Q\) (tabela de quantização, inteiros positivos).
Saída:
- Matriz reconstruída \(C'\), \(N \times N\), inteiros separados por espaço.
5.13.3.5 📌 Exemplos
| Entrada | Saída | Observação |
|---|---|---|
| 4 50 10 -5 0 8 -3 2 1 0 1 0 0 2 0 0 -1 2 5 7 8 4 7 8 11 6 8 11 12 9 11 12 14 |
50 10 -7 0 8 0 0 0 0 0 0 0 0 0 0 0 |
\(C(0,0)=50/2=25 \to 25\times2=50\) (preservado). \(C(0,2)=-5/7\approx-0.71\to-1\to-1\times7=-7\). Já \(C(1,1)=-3/7\approx-0.43\to0\): zerado pela quantização — a maior parte do bloco vira zero, ilustrando a compactação de energia no canto superior esquerdo. |
%%writefile EP05_03.cpp
// sua soluçãoOverwriting EP05_03.cpp
TestSuite("EP05_03.cpp").run()✔️ EP05_03.cases já existe em casos/
📋 5 caso(s) carregado(s) de casos/EP05_03.cases
🔍 Testando C++: EP05_03.cpp
⚠️ EP05_03.cpp: Arquivo sem conteúdo (menos de 3 linhas). Testes ignorados.