Como funciona o formato JPEG

As imagens JPEG são onipresentes em nossas vidas digitais, mas por trás dessa aparência de consciência estão algoritmos que removem detalhes que não são perceptíveis ao olho humano. O resultado é a mais alta qualidade visual no menor tamanho de arquivo - mas como exatamente tudo funciona? Vamos ver o que exatamente nossos olhos não veem!

Como funciona o formato JPEG

É fácil considerar a capacidade de enviar uma foto para um amigo e não se preocupar com o dispositivo, navegador ou sistema operacional que ele está usando - mas nem sempre foi assim. No início da década de 1980, os computadores podiam armazenar e exibir imagens digitais, mas havia muitas ideias concorrentes sobre a melhor maneira de fazer isso. Você não poderia simplesmente enviar uma imagem de um computador para outro e esperar que funcionasse.

Para resolver este problema, um comitê de especialistas de todo o mundo foi reunido em 1986 chamado "Grupo Conjunto de Especialistas em Fotografia» (Joint Photographic Experts Group, JPEG), fundado como um esforço conjunto entre a Organização Internacional de Normalização (ISO) e a Comissão Eletrotécnica Internacional (IEC), duas organizações de normalização internacionais com sede em Genebra, Suíça.

Um grupo de pessoas chamado JPEG criou o padrão de compressão de imagens digitais JPEG em 1992. Qualquer pessoa que tenha usado a Internet provavelmente já encontrou imagens codificadas em JPEG. Esta é a forma mais comum de codificar, enviar e armazenar imagens. De páginas da web a e-mails e mídias sociais, o JPEG é usado bilhões de vezes por dia – praticamente sempre que visualizamos uma imagem on-line ou a enviamos. Sem JPEG, a web seria menos colorida, mais lenta e provavelmente teria menos fotos de gatos!

Este artigo é sobre como decodificar uma imagem JPEG. Em outras palavras, o que é necessário para converter dados compactados armazenados em um computador em uma imagem que aparece na tela. Vale a pena conhecer isso, não só porque é importante para entender a tecnologia que usamos todos os dias, mas também porque ao desbloquear os níveis de compressão, aprendemos mais sobre percepção e visão, e a quais detalhes nossos olhos são mais sensíveis.

Além disso, brincar com as imagens dessa forma é muito interessante.

Como funciona o formato JPEG

Olhando dentro do JPEG

Num computador, tudo é armazenado como uma sequência de números binários. Normalmente esses bits, zeros e uns, são agrupados em grupos de oito para formar bytes. Ao abrir uma imagem JPEG em um computador, algo (um navegador, um sistema operacional, qualquer outra coisa) deve decodificar os bytes, restaurando a imagem original como uma lista de cores que podem ser exibidas.

Se você baixar este doce foto de um gato e abri-lo em um editor de texto, você verá vários caracteres incoerentes.

Como funciona o formato JPEG
Aqui estou usando o Notepad++ para examinar o conteúdo do arquivo, já que editores de texto comuns como o Notepad no Windows corromperão o arquivo binário após salvá-lo e não atenderão mais ao formato JPEG.

Abrir uma imagem em um processador de texto confunde o computador, assim como você confunde seu cérebro quando esfrega os olhos e começa a ver manchas coloridas!

Esses pontos que você vê são conhecidos como fosfenos, e não são o resultado de um estímulo luminoso ou de uma alucinação gerada pela mente. Eles ocorrem porque seu cérebro pensa que quaisquer sinais elétricos nos nervos ópticos transmitem informações sobre a luz. O cérebro precisa fazer essas suposições porque não há como saber se um sinal é um som, uma visão ou qualquer outra coisa. Todos os nervos do corpo transmitem exatamente os mesmos impulsos elétricos. Ao aplicar pressão nos olhos, você envia sinais que não são visuais, mas ativam os receptores oculares, que seu cérebro interpreta – neste caso, incorretamente – como algo visual. Você pode literalmente ver a pressão!

É engraçado pensar em como os computadores são semelhantes ao cérebro, mas também é uma analogia útil para ilustrar o quanto o significado dos dados – sejam transportados pelo corpo pelos nervos ou armazenados num computador – depende de como são interpretados. Todos os dados binários são compostos de XNUMXs e XNUMXs, os componentes básicos que podem transmitir informações de qualquer tipo. Seu computador geralmente descobre como interpretá-los usando pistas como extensões de arquivo. Agora forçamos a interpretá-los como texto, porque é isso que o editor de texto espera.

Para entender como decodificar JPEG, precisamos ver os próprios sinais originais – os dados binários. Isso pode ser feito usando um editor hexadecimal ou diretamente no página da web do artigo original! Há uma imagem, ao lado da qual no campo de texto estão todos os seus bytes (exceto o cabeçalho), apresentados em forma decimal. Você pode alterá-los e o script irá recodificar e produzir uma nova imagem instantaneamente.

Como funciona o formato JPEG

Você pode aprender muito apenas brincando com este editor. Por exemplo, você pode dizer em que ordem os pixels são armazenados?

O estranho neste exemplo é que alterar alguns números não afeta em nada a imagem, mas, por exemplo, se você substituir o número 17 por 0 na primeira linha, a foto ficará completamente estragada!

Como funciona o formato JPEG

Outras mudanças, como substituir o 7 na linha 1988 pelo número 254, alteram a cor, mas apenas dos pixels subsequentes.

Como funciona o formato JPEG

Talvez o mais estranho seja que alguns números alteram não só a cor, mas também o formato da imagem. Mude 70 na linha 12 para 2 e olhe para a linha superior da imagem para ver o que quero dizer.

Como funciona o formato JPEG

E não importa qual imagem JPEG você use, você sempre encontrará esses misteriosos padrões de xadrez ao editar os bytes.

Ao brincar com o editor, fica difícil entender como uma foto é recriada a partir desses bytes, pois a compressão JPEG consiste em três tecnologias diferentes, aplicadas sequencialmente em níveis. Estudaremos cada um separadamente para descobrir o comportamento misterioso que estamos vendo.

Três níveis de compactação JPEG:

  1. Subamostragem de cores.
  2. Transformada discreta de cosseno e amostragem.
  3. Codificação de comprimento de execução, delta и Huffman

Para se ter uma ideia da magnitude da compressão, observe que a imagem acima representa 79 números, ou cerca de 819 KB. Se o armazenássemos sem compactação, cada pixel exigiria três números – para os componentes vermelho, verde e azul. Isso equivaleria a 79 números, ou aprox. 917KB. Como resultado da compactação JPEG, o arquivo final foi reduzido em mais de 700 vezes!

Na verdade, esta imagem pode ser muito mais compactada. Abaixo estão duas imagens lado a lado - a foto da direita foi compactada para 16 KB, ou seja, 57 vezes menor que a versão descompactada!

Como funciona o formato JPEG

Se você olhar com atenção, verá que essas imagens não são idênticas. Ambas são imagens com compactação JPEG, mas a da direita tem volume bem menor. Também parece um pouco pior (observe os quadrados da cor de fundo). É por isso que JPEG também é chamado de compactação com perdas; Durante o processo de compactação, a imagem muda e perde alguns detalhes.

1. Subamostragem de cores

Aqui está uma imagem com apenas o primeiro nível de compactação aplicado.

Como funciona o formato JPEG
(Versão interativa - em o original artigos). A remoção de um número destrói todas as cores. No entanto, se exatamente seis números forem removidos, praticamente não haverá efeito na imagem.

Agora os números são um pouco mais fáceis de decifrar. Trata-se de uma lista quase simples de cores, em que cada byte altera exatamente um pixel, mas ao mesmo tempo já tem metade do tamanho da imagem descompactada (que ocuparia cerca de 300 KB neste tamanho reduzido). Você consegue adivinhar por quê?

Você pode ver que esses números não representam os componentes padrão vermelho, verde e azul, pois se substituirmos todos os números por zeros, obteremos uma imagem verde (em vez de branca).

Como funciona o formato JPEG

Isso ocorre porque esses bytes representam Y (brilho),

Como funciona o formato JPEG

Cb (azul relativo),

Como funciona o formato JPEG

e fotos de Cr (vermelhidão relativa).

Como funciona o formato JPEG

Por que não usar RGB? Afinal, é assim que funciona a maioria das telas modernas. Seu monitor pode exibir qualquer cor, incluindo vermelho, verde e azul, com intensidades diferentes para cada pixel. O branco é obtido ligando todos os três com brilho total, e o preto, desligando-os.

Como funciona o formato JPEG

Isso também é muito semelhante ao funcionamento do olho humano. Os receptores de cores em nossos olhos são chamados de "cones“, e são divididos em três tipos, cada um dos quais é mais sensível às cores vermelha, verde ou azul [os cones do tipo S são sensíveis no azul-violeta (S do inglês Short - espectro de ondas curtas), M -tipo - nas partes verde-amarela (M do inglês Médio - onda média) e tipo L - nas partes amarelo-vermelho (L do inglês Long - onda longa) do espectro. A presença desses três tipos de cones (e bastonetes, que são sensíveis na parte verde esmeralda do espectro) dá à pessoa uma visão colorida. / Aproximadamente. trad.]. Varas, outro tipo de fotorreceptor dos nossos olhos, é capaz de detectar alterações no brilho, mas é muito mais sensível à cor. Nossos olhos têm cerca de 120 milhões de bastonetes e apenas 6 milhões de cones.

É por isso que nossos olhos são muito melhores em detectar mudanças no brilho do que mudanças na cor. Se você separar a cor do brilho, poderá remover um pouco de cor e ninguém notará nada. A subamostragem de croma é o processo de representar os componentes de cor de uma imagem em uma resolução mais baixa do que os componentes de luminância. No exemplo acima, cada pixel possui exatamente um componente Y, e cada grupo individual de quatro pixels possui exatamente um componente Cb e um componente Cr. Portanto, a imagem contém quatro vezes menos informações de cores que a original.

O espaço de cores YCbCr não é usado apenas em JPEG. Foi originalmente inventado em 1938 para programas de televisão. Nem todo mundo tem uma TV em cores, então separar cor e brilho permitiu que todos obtivessem o mesmo sinal, e as TVs sem cores simplesmente usavam apenas o componente de brilho.

Portanto, remover um número do editor estraga completamente todas as cores. Os componentes são armazenados no formato AAAA Cb Cr (na verdade, não necessariamente nessa ordem - a ordem de armazenamento é especificada no cabeçalho do arquivo). A remoção do primeiro número fará com que o primeiro valor de Cb seja percebido como Y, Cr como Cb e, em geral, você terá um efeito dominó que muda todas as cores da imagem.

A especificação JPEG não obriga você a usar YCbCr. Mas a maioria dos arquivos o utiliza porque produz imagens com resolução reduzida melhor do que RGB. Mas você não precisa acreditar apenas na minha palavra. Veja você mesmo na tabela abaixo como será a subamostragem de cada componente individual em RGB e YCbCr.

Como funciona o formato JPEG
(Versão interativa - em o original artigos).

A remoção do azul não é tão perceptível quanto a do vermelho ou do verde. Isso porque dos seis milhões de cones nos seus olhos, cerca de 64% são sensíveis ao vermelho, 32% ao verde e 2% ao azul.

A redução da resolução do componente Y (canto inferior esquerdo) é melhor visualizada. Mesmo uma pequena mudança é perceptível.

Converter uma imagem de RGB para YCbCr não reduz o tamanho do arquivo, mas facilita a localização de detalhes menos visíveis que podem ser removidos. A compressão com perdas ocorre no segundo estágio. Baseia-se na ideia de apresentar os dados de uma forma mais compressível.

2. Transformada discreta de cosseno e amostragem

Esse nível de compactação é, em grande parte, a essência do JPEG. Depois de converter as cores para YCbCr, os componentes são compactados individualmente, para que possamos nos concentrar apenas no componente Y. E aqui está a aparência dos bytes do componente Y após a aplicação desta camada.

Como funciona o formato JPEG
(Versão interativa - em o original artigos). Na versão interativa, clicar em um pixel rola o editor até a linha que o representa. Tente remover os números do final ou adicionar alguns zeros a um determinado número.

À primeira vista, parece uma compressão muito ruim. Existem 100 pixels em uma imagem e são necessários 000 números para representar seu brilho (componentes Y) – isso é pior do que não compactar nada!

No entanto, observe que a maioria desses números é zero. Além disso, todos aqueles zeros no final das linhas podem ser removidos sem alterar a imagem. Restam cerca de 26 números, e isso é quase 000 vezes menos!

Este nível contém o segredo dos padrões de xadrez. Ao contrário de outros efeitos que vimos, o aparecimento destes padrões não é uma falha. Eles são os blocos de construção de toda a imagem. Cada linha do editor contém exatamente 64 números, coeficientes de transformada discreta de cosseno (DCT) correspondentes às intensidades de 64 padrões únicos.

Esses padrões são formados com base no gráfico de cossenos. Aqui está a aparência de alguns deles:

Como funciona o formato JPEG
8 de 64 probabilidades

Abaixo está uma imagem mostrando todos os 64 padrões.

Como funciona o formato JPEG
(Versão interativa - em o original artigos).

Esses padrões são de particular importância porque constituem a base das imagens 8x8. Se você não está familiarizado com álgebra linear, isso significa que qualquer imagem 8x8 pode ser criada a partir desses 64 padrões. DCT é o processo de dividir imagens em blocos de 8x8 e converter cada bloco em uma combinação desses 64 coeficientes.

Parece mágico que qualquer imagem possa ser composta por 64 padrões específicos. No entanto, isto é o mesmo que dizer que qualquer lugar na Terra pode ser descrito por dois números - latitude e longitude [indicando hemisférios / aprox. trad.]. Muitas vezes pensamos na superfície da Terra como bidimensional, por isso só precisamos de dois números. Uma imagem 8x8 tem 64 dimensões, então precisamos de 64 números.

Ainda não está claro como isso nos ajuda em termos de compressão. Se precisarmos de 64 números para representar uma imagem 8x8, por que isso seria melhor do que apenas armazenar 64 componentes de brilho? Fazemos isso pela mesma razão que transformamos três números RGB em três números YCbCr: isso nos permite remover detalhes sutis.

É difícil ver exatamente quais detalhes são removidos neste estágio porque o JPEG aplica DCT a blocos 8x8. No entanto, ninguém nos proíbe de aplicá-lo ao quadro geral. Esta é a aparência do DCT para o componente Y aplicado à imagem inteira:

Como funciona o formato JPEG

Mais de 60 números podem ser removidos do final praticamente sem alterações perceptíveis na foto.

Como funciona o formato JPEG

No entanto, note que se zerarmos os primeiros cinco números, a diferença será óbvia.

Como funciona o formato JPEG

Os números no início representam mudanças de baixa frequência na imagem, que nossos olhos captam melhor. Os números no final indicam mudanças nas altas frequências que são mais difíceis de notar. Para “ver o que o olho não pode ver”, podemos isolar esses detalhes de alta frequência zerando os primeiros 5000 números.

Como funciona o formato JPEG

Vemos todas as áreas da imagem onde ocorre a maior mudança de pixel para pixel. Destacam-se os olhos do gato, os bigodes, a manta felpuda e as sombras no canto inferior esquerdo. Você pode ir além zerando os primeiros 10 números:

Como funciona o formato JPEG

20 000:

Como funciona o formato JPEG

40 000:

Como funciona o formato JPEG

60 000:

Como funciona o formato JPEG

Esses detalhes de alta frequência são removidos pelo JPEG durante o estágio de compactação. Não há perda na conversão de cores em coeficientes DCT. A perda ocorre na etapa de amostragem, onde são removidos valores de alta frequência ou próximos de zero. Ao diminuir a qualidade de salvamento do JPEG, o programa aumenta o limite para o número de valores removidos, o que reduz o tamanho do arquivo, mas torna a imagem mais pixelizada. É por isso que a imagem da primeira seção, que era 57 vezes menor, ficou assim. Cada bloco 8x8 foi representado por muito menos coeficientes DCT em comparação com a versão de qualidade superior.

Você pode criar um efeito legal como o streaming gradual de imagens. Você pode exibir uma imagem borrada que se torna cada vez mais detalhada à medida que mais e mais coeficientes são baixados.

Aqui, apenas por diversão, está o que você obtém usando apenas 24 números:

Como funciona o formato JPEG

Ou apenas 5000:

Como funciona o formato JPEG

Muito embaçado, mas de alguma forma reconhecível!

3. Codificação de comprimento de execução, delta e Huffman

Até agora, todos os estágios de compactação apresentaram perdas. A última etapa, ao contrário, transcorre sem perdas. Não exclui informações, mas reduz significativamente o tamanho do arquivo.

Como você pode compactar algo sem jogar fora informações? Imagine como descreveríamos um retângulo preto simples de 700 x 437.

JPEG usa 5000 números para isso, mas resultados muito melhores podem ser alcançados. Você consegue imaginar um esquema de codificação que descreveria tal imagem no menor número possível de bytes?

O esquema mínimo que consegui criar usa quatro: três para representar uma cor e um quarto para indicar quantos pixels essa cor possui. A ideia de representar valores repetidos dessa forma condensada é chamada de codificação run-length. Não tem perdas porque podemos restaurar os dados codificados à sua forma original.

Um arquivo JPEG com um retângulo preto é muito maior que 4 bytes - lembre-se de que no nível DCT a compactação é aplicada a blocos de 8x8 pixels. Portanto, precisamos no mínimo de um coeficiente DCT para cada 64 pixels. Precisamos de um porque, em vez de armazenar um coeficiente DCT seguido de 63 zeros, a codificação de comprimento de execução nos permite armazenar um número e indicar que “todos os outros são zeros”.

A codificação delta é uma técnica na qual cada byte contém uma diferença de algum valor, em vez de um valor absoluto. Portanto, a edição de determinados bytes altera a cor de todos os outros pixels. Por exemplo, em vez de armazenar

12 13 14 14 14 13 13 14

Poderíamos começar com 12 e depois simplesmente indicar quanto precisamos de adicionar ou subtrair para obter o próximo número. E esta sequência na codificação delta assume a forma:

12 1 1 0 0 -1 0 1

Os dados convertidos não são menores que os dados originais, mas são mais fáceis de compactar. Aplicar a codificação delta antes da codificação do comprimento da execução pode ajudar muito e ainda ser uma compactação sem perdas.

A codificação delta é uma das poucas técnicas usadas fora dos blocos 8x8. Dos 64 coeficientes DCT, um é simplesmente uma função de onda constante (cor sólida). Representa o brilho médio de cada bloco para os componentes luma, ou o azul médio para os componentes Cb, e assim por diante. O primeiro valor de cada bloco DCT é chamado de valor DC, e cada valor DC é codificado em delta em relação aos anteriores. Portanto, alterar o brilho do primeiro bloco afetará todos os blocos.

O mistério final permanece: como é que a mudança do singular arruína completamente todo o quadro? Até agora, os níveis de compressão não possuíam tais propriedades. A resposta está no cabeçalho JPEG. Os primeiros 500 bytes contêm metadados sobre a imagem - largura, altura, etc., e ainda não trabalhamos com eles.

Sem cabeçalho é quase impossível (ou muito difícil) decodificar JPEG. Parecerá que estou tentando descrever a imagem para você e começando a inventar palavras para transmitir minha impressão. A descrição provavelmente será bastante condensada, pois posso inventar palavras exatamente com o significado que quero transmitir, mas para todos os outros elas não farão sentido.

Parece estúpido, mas é exatamente isso que acontece. Cada imagem JPEG é compactada com códigos específicos para ela. O dicionário de código é armazenado no cabeçalho. Essa técnica é chamada de código de Huffman e o vocabulário é chamado de tabela de Huffman. No cabeçalho, a tabela é marcada com dois bytes - 255 e depois 196. Cada componente de cor pode ter sua própria tabela.

As alterações nas tabelas afetarão radicalmente qualquer imagem. Um bom exemplo é alterar a 15ª linha para 1.

Como funciona o formato JPEG

Isso acontece porque as tabelas especificam como os bits individuais devem ser lidos. Até agora trabalhamos apenas com números binários na forma decimal. Mas isso nos esconde o fato de que se quisermos armazenar o número 1 em um byte, ele se parecerá com 00000001, pois cada byte deve ter exatamente oito bits, mesmo que apenas um deles seja necessário.

Isto é potencialmente um grande desperdício de espaço se você tiver muitos números pequenos. O código de Huffman é uma técnica que nos permite flexibilizar a exigência de que cada número deve ocupar oito bits. Isso significa que se você vir dois bytes:

234 115

Então, dependendo da tabela de Huffman, estes poderiam ser três números. Para extraí-los, você precisa primeiro dividi-los em partes individuais:

11101010 01110011

Em seguida, olhamos para a tabela para descobrir como agrupá-los. Por exemplo, podem ser os primeiros seis bits (111010) ou 58 em decimal, seguidos por cinco bits (10011) ou 19 e, finalmente, os últimos quatro bits (0011) ou 3.

Portanto, é muito difícil compreender os bytes nesta fase de compressão. Bytes não representam o que parecem. Não entrarei em detalhes sobre como trabalhar com a tabela neste artigo, mas materiais sobre este assunto on-line suficiente.

Um truque interessante que você pode fazer com esse conhecimento é separar o cabeçalho do JPEG e armazená-lo separadamente. Na verdade, só você pode ler o arquivo. O Facebook faz isso para tornar os arquivos ainda menores.

O que mais pode ser feito é mudar um pouco a tabela de Huffman. Para outros, parecerá uma imagem quebrada. E só você saberá a maneira mágica de consertar isso.

Vamos resumir: então o que é necessário para decodificar JPEG? Necessário:

  1. Extraia a(s) tabela(s) Huffman do cabeçalho e decodifique os bits.
  2. Extraia os coeficientes de transformação discreta de cosseno para cada componente de cor e luminância para cada bloco 8x8, realizando transformações inversas de comprimento de execução e codificação delta.
  3. Combine cossenos com base em coeficientes para obter valores de pixel para cada bloco 8x8.
  4. Dimensione os componentes de cores se a subamostragem tiver sido realizada (esta informação está no cabeçalho).
  5. Converta os valores YCbCr resultantes de cada pixel para RGB.
  6. Exiba a imagem na tela!

Trabalho sério simplesmente ver uma foto com um gato! No entanto, o que mais gosto nisso é que mostra como a tecnologia JPEG é centrada no ser humano. Baseia-se nas peculiaridades da nossa percepção, permitindo-nos obter uma compressão muito melhor do que as tecnologias convencionais. E agora que entendemos como funciona o JPEG, podemos imaginar como essas tecnologias podem ser transferidas para outras áreas. Por exemplo, a codificação delta em vídeo pode proporcionar uma redução significativa no tamanho do arquivo, uma vez que muitas vezes há áreas inteiras que não mudam de quadro para quadro (por exemplo, o plano de fundo).

Código usado no artigo, está aberto e contém instruções sobre como substituir as imagens pelas suas próprias.

Fonte: habr.com

Adicionar um comentário