Multimídia – Técnicas de Compactação e Compressão Prof. Lucas Lattari lucas.lattari@ifsudestemg.edu.br
Introdução Compactação X Compressão Classificação das técnicas de compressão Codificação por Entropia, na Origem e Híbrida Técnicas de Compactação Codificação por carreira Codificação por Shannon-Fano Codificação de Huffman Codificação de Lempel-Ziv-Welch (LZW) Codificação aritmética
Introdução Técnicas de Compressão Redução do domínio Redução do espaço de quantização Codificação preditiva Codificação por sub-bandas Codificação por transformadas Quantização vetorial
Motivação Como visto anteriormente, as diversas mídias podem requerer uma banda passante de rede não disponíveis Imagem: 18,9 Mbits para imagem 1024×768 a 24bpp ≈2,5Mbits para imagem VGA a 8bpp Áudio: 64 kbps (voz, mono, qualidade de telefone) 1,411 Mbps (música, stereo, qualidade de CD) Vídeo: ≈ 332 Mbps para 𝑌 𝐶 𝑟 𝐶 𝑏 para vídeo 4:2:2 Similarmente, usuários de redes com cobrança por quantidade de dados transmitidos (ou quantidade de tempo de conexão) se beneficiariam da diminuição de quantidade de dados enviados na rede.
Compressão de Dados Função realizada sobre dados antes da transmissão. Codificador da Origem (Source Coder) Decodificador do Destino (Destination Decoder) Usada para reduzir o volume de informação a ser transmitida ou reduzir a banda passante necessária para transmissão dos dados Compressão com perdas e sem perdas
Compactação x Compressão Quando eliminamos apenas a redundância de um sinal Não há perda de informação Compressão sem perdas Podem ser usadas para qualquer sinal, mas geralmente são usados em textos ou arquivos binários Compressão: Quando, na redução dos dados, há perda de informação Compressão com perdas Algumas técnicas são usadas em sinais específicos, como imagem, aúdio e vídeo Compressão perceptualmente sem perdas humanos não percebem Ex.: MP3 para áudio
Classificação das Técnicas de Compactação / Compressão Codificação por Entropia trata cadeias de bits sem levar em conta seu significado técnica genérica, sem perda e totalmente reversível Ex.: técnicas de compactação: codificação por carreira, codificação de Huffman, codificação aritmética etc Codificação na Origem leva em consideração a semântica dos dados processa o dado original distinguindo o dado relevante e o irrelevante removendo dados irrelevantes comprime o dado original Ex.: técnicas de compressão: codificação preditiva, codificação por sub-bandas, codificação por transformadas, quantização vetorial etc Codificações Híbridas Combinam técnicas com e sem perdas (várias técnicas são agrupadas para formar uma nova técnica de codagem) Ex.: JPEG, MPEG, H.263 etc
Codificação por Carreira (Run-Length) Usada quando o sinal a ser modificado contém uma longa sequência de bits repetidos Sequência de bits é substituída pelo bit e indicação de quantidade do mesmo Exemplo: 000000011111111110000011 ... -> 0,7,1,10,0,5,1,2 Assumindo que a sequência sempre inicia com zeros -> 7,10,5,2
Conceitos de Teoria da Informação Entropia: ɲ= 𝑖=1 𝑛 𝑝 𝑖 . 𝑙𝑜𝑔 2 1 𝑝 𝑖 Onde 𝑝 𝑖 é a probabilidade de ocorrência de um símbolo 𝑠 𝑖 (de um alfabeto S) na informação Neste contexto, entropia indica a quantidade média de bits para representar uma informação Quanto maior a entropia, menor será a compressão Uma série de métodos de codificação se baseiam no conceito de entropia
Algoritmos de Compactação Algoritmo de Shannon - Fano Algoritmo de Huffman Ambos os algoritmos montam seus códigos através da criação de uma árvore binária O código é mínimo: Se um símbolo 𝑠 𝑖 tem grande frequência de ocorrência na informação, então o comprimento do seu código será menor; caso contrário, o código será maior O número médio de bits será o menor inteiro maior que a entropia ɲ
Algoritmo de Shannon-Fano Considere uma informação que contém o alfabeto S = {A, B, C, D, E} com as seguintes ocorrências A = 15 B = 7 C = 6 D = 6 E = 5
Algoritmo de Shannon-Fano As probabilidades são: 𝑝 𝑎 = 15 39 𝑝 𝑏 = 7 39 𝑝 𝑐 = 6 39 𝑝 𝑑 = 6 39 𝑝 𝑒 = 5 39 Calculando-se a entropia, tem-se: ɲ=2,19≤3 𝑏𝑖𝑡𝑠
Algoritmo de Shannon-Fano Ao calcular a entropia, tem-se uma noção do número de bits médio de cada símbolo Após computar a frequência de cada símbolo, ordene-os de maneira decrescente No exemplo atual, a ordem seria ABCDE Para cada iteração, divida recursivamente os símbolos em 2 partes, cada uma com aproximadamente o mesmo número de contagem Observe o slide a seguir
Algoritmo de Shannon-Fano
Algoritmo de Shannon-Fano
Algoritmo de Shannon-Fano Por exemplo, a codificação ABDEACD ficaria: 00 01 110 111 00 10 110 Para que a codificação e a decodificação seja possível, o sistema deverá ter acesso aos: Símbolos Árvore Sequência
Codificação de Huffman Codificação Estatística A sequência a ser compactada deve ser analisada previamente, identificando-se os caracteres e suas respectivas frequências/probabilidades Atribui menos bits a símbolos que aparecem mais frequentemente e mais bits para símbolos que aparecem menos
Codificação de Huffman Algoritmo Insira os nós contendo símbolos e frequências em uma lista Repita os passos abaixo até que a lista contenha apenas um nós Selecione os dois nós com menor frequência e crie um nó pai para ambos Atribua ao nó pai a soma das frequências e insira-o na lista Atribua os códigos 0 e 1 aos dois ramos da árvore e retire os filhos da lista
Codificação de Huffman
Codificação de Huffman
Codificação de Huffman O algoritmo de Shannon-Fano é um pouco inferior a codificação de Huffman A decodificação de ambos os métodos é simples, basta ler a sequência de bits e, sempre que uma sequência for identificada, ela é traduzida
Codificação de Huffman Nem todos os caracteres precisam ter uma representação codificada na tabela de Huffman Apenas os caracteres com alta probabilidade de ocorrência Demais são codificados diretamente e marcados com uma flag especial Técnica útil quando o número de caracteres diferentes é muito grande mas apenas alguns têm uma alta probabilidade de ocorrência
Codificação Aritmética Utiliza um único código por string de caracteres codificada A sequência a ser compactada deve ser analisada previamente, identificando-se os caracteres e suas respectivas frequências/probabilidades Exemplo: e=0.3; n=0.3; t=0.2; w=0.1; .=0.1 Precisa de um caractere marcando o fim de cada sequência (.) Algoritmo: Dividir o intervalo de [0, 1] de acordo com a probabilidade de ocorrência de cada caractere na sequência Repita até o caractere de fim de sequência Escolha o intervalo correspondente ao próximo caractere e divida-o novamente de acordo com as probabilidades iniciais O código pode ser qualquer número dentro do último intervalo encontrado
Codificação Aritmética
Codificação Aritmética O número de dígitos decimais no código aumenta linearmente conforme o número de caracteres na string O número máximo de caracteres em uma string é determinado pela precisão com a qual números de ponto flutuante são representados nos computadores de origem e destino Por essa razão, mensagens completas devem ser fragmentadas em várias strings menores e cada string deve ser codificada separadamente
Codificação de Lempel-Ziv Codificação de Lempel-Ziv (LZ) Ao invés de utilizar caracteres como a base da codificação, utiliza strings de caracteres É baseada na construção de um dicionário de frases (grupos de um ou mais caracteres) a partir do fluxo de entrada Quando uma nova frase é encontrada Ela é adicionada ao dicionário Se a frase encontrada já foi registrada Ela é substituída pelo código no dicionário Esta técnica é boa para compressão de arquivos textos, onde temos uma grande repetição de frases Exemplo em português: "ela", "Contudo", "onde"
Codificação de Lempel-Ziv Algoritmo inicia com uma tabela de códigos com todos os caracteres existentes na string que pretende-se compactar A codificação se inicia definindo a sequência de símbolos a ser compactada Se não existem mais símbolos a ser codificados, o algoritmo termina. Caso contrário, Pegue o próximo símbolo codificado que aparecer e concatene ao anterior, formando uma nova sequência codificada e adicionada ao dicionário Retorne ao passo 1
Codificação de Lempel-Ziv Exemplo Compressão da cadeia de caracteres ABACABA Primeiro passo: inicializar a tabela de códigos com todos os caracteres existentes na string a ser compactada #0 = A, #1 = B, #2 = C Caractere A (primeiro da sequência) É codificada como #0 AB é adicionada ao dicionário como #3 Caractere B (segundo da sequência) B é concatenado e AB é codificada como #0#1 BA é adicionado ao dicionário como #4 Caractere A (terceiro da sequência) A é concatenado e ABA é codificada como #0#1#0 AC é adicionada ao dicionário como #5
Codificação de Lempel-Ziv Exemplo Compressão da cadeia de caracteres ABACABA Tabela atual: #0 = A, #1 = B, #2 = C, #3 = AB, #4 = BA, #5 = AC Caractere C (quarto da sequência) C é concatenado e sequência ABAC é codificada como #0#1#0#2 CA é adicionada ao dicionário como #6 Caractere AB (quinto e sexto da sequência) AB é concatenada e ABACAB é codificada como #0#1#0#2#3 BA é adicionado ao dicionário como #4 Caractere A (último da sequência) A é concatenado ao final e sequência é codificada como #0#1#0#2#3#0 Com a sequência toda codificada o algoritmo é encerrado
Codificação de Lempel-Ziv-Welch Codificador e decodificador constroem o conteúdo do dicionário dinamicamente enquanto o texto é processado Inicialmente, o dicionário contém somente o conjunto de caracteres que foi usado na construção do texto (ex. ASCII 7 bits) As entradas restantes são utilizadas para codificar palavras que ocorrem no texto Exemplo: This is simple as it is ...
Codificação de Lempel-Ziv-Welch
Codificação de Lempel-Ziv-Welch
Algoritmo LZ77 Variação do LZW usado em vários compactadores comerciais PKZIP/PKUNZIP (para o DOS) ARJ GZIP/GUNZIP Compress/Uncompress (para o UNIX) PNG Princípio de funcionamento: Em uma sequência de caracteres, o algoritmo procura na janela corrente a maior subsequência que casa com o início do lookahead buffer e dá como saída um ponteiro para o início da sub-sequência na janela e o primeiro caracter no lookahead buffer que não casa com a sequência Se não houver subsequência, a saída é um ponteiro nulo e o caractere na posição atual da sequência original
Algoritmo LZ77 Termos usados no algoritmo: Sequência de entrada Sequência de caracteres a ser comprimida Caractere Elemento básico da sequência encontrada Posição atual Posição do caractere na sequência de entrada que está sendo codificado no momento (início do lookahead buffer) Lookahead Buffer: Sequência de caracteres a partir da posição atual até o fim da sequência de entrada
Algoritmo LZ77 Termos usados no algoritmo: Janela Janela de tamanho W contém W caracteres a partir da posição atual em direção ao início da sequência de entrada, i.e. os últimos W caracteres processados Ponteiro Aponta para a sequência que casa na janela e também indica seu comprimento (L)
Algoritmo LZ77 Algoritmo: Faça posição atual igual ao início da seqüência de entrada Encontre a maior subsequência (longest match) na janela que casa com o conteúdo do lookahead buffer Dê como saída o par (P,C), onde: P é o ponteiro para a subsequência na janela C é o primeiro caracter no lookahead buffer que não casa com a subsequência Se o lookahead buffer não estiver vazio, mova a posição atual (e a janela) L+1 caracteres para frente e volte para o passo 2 (L é o comprimento da subsequência)
Algoritmo LZ77 Primeiro exemplo Compressão da cadeia “A_ASA_DA_CASA” usando janela de tamanho 8 e buffer de lookahead de tamanho 4 Janela Buffer Lookahead Restante do Arquivo Tupla Emitida A_AS A_DA_CASA (0, 0, A) A _ASA _DA_CASA (0, 0, _) A_ ASA_ DA_CASA (1, 1, S) A_DA _CASA (3, 2, D) A_ASA_D A_CA SA (2, 2, C) A_ASA_DA_C ASA (7, 3, EOF)
Algoritmo LZ77 Segundo exemplo Compressão da cadeia “AABCBBABC” usando janela de tamanho 10 e buffer de lookahead de tamanho 4 Janela Buffer Lookahead Restante do Arquivo Tupla Emitida AABC BBABC (0, 0, A) A ABCB BABC (1, 1, B) AAB CBBA BC (0, 0, C) BBAB C (2, 1, B) AABCBB ABC (5, 2, C)
Algoritmo LZ77 Decodificação A janela é mantida da mesma forma que na codificação Em cada passo, o algoritmo lê o par (P,C) da entrada e dá como saída a sequência da janela a partir de P seguida do caracter C Exemplo: (0,0)A (1,1)B (0,0)C (2,1)B (5,2)C 1. (0,0)A => W = nula, saída = A 2. (1,1)B => W = A, saída = AAB 3. (0,0)C => W = AAB, saída = AABC 4. (2,1)B => W = AABC, saída = AABCBB 5. (5,3)C = > W = AABCBB, saída = AABCBBABC
Algoritmo LZ77 Considerações principais: Boa taxa de compressão para vários tipos de dados Codificação pode ser lenta, já que várias comparações são feitas entre o lookahead buffer e a janela Decodificação muito simples e rápida Requisitos de memória são poucos tanto para codificação quanto para decodificação A única estrutura mantida em memória é a janela, que normalmente tem tamanho entre 4 e 64 KB
Técnicas de Compressão Quando, na redução dos dados, há perda de informação Compressão com perdas Algumas técnicas são usadas em sinais específicos Compressão perceptualmente sem perdas humanos não percebem Ex.: MP3 para áudio Técnicas Redução do domínio Redução do espaço de quantização Codificação preditiva Codificação por sub-bandas Codificação por transformadas Quantização vetorial
Redução do Domínio Idéia básica Ex.: padrões para vídeo digital Simplesmente descarta algumas amostras Ex.: padrões para vídeo digital Formatos 4:2:2, 4:2:0 Informações de luminância são mais importantes que crominância, então o número de amostras de crominância pode ser menor Ex.: compressão em imagens diminui a resolução geométrica aumenta o tamanho do pixel
Redução do Domínio em Imagens
Redução do Espaço de Quantização Idéia básica Diminuir a quantidade de bits por amostra Ex.: compressão de imagens Imagem original com 24 bits por pixel (16 milhões de cores) Imagem comprimida com 8 bits por pixel (256 cores) fazendo uma correspondência entre os códigos
Codificação Preditiva Codificação diferencial ou codificação relativa Idéia básica Amplitude de uma amostra é grande, mas a diferença de amplitude entre amostras sucessivas é relativamente pequena Ao invés de codificar o valor de cada amostra, codifica a diferença entre seu valor e o anterior Utiliza menos bits e obtém o mesmo erro Ex.: DPCM (Differential Pulse Code Modulation) ADPCM (Adaptive Differential Pulse Code Modulation)
Codificação por Sub-Bandas Idéia básica Divisão da banda passante do sinal em várias sub-bandas codificadas de forma distinta Trata com maior precisão as sub-bandas mais importantes do sinal Por exemplo, sinal de voz: 300-800Hz – qualidade e timbre 8 bits por amostra 800-1400Hz – pouca informação 2 bits por amostra 1400-2400Hz – reconhecimento e intelegibilidade Maior informação de conteúdo (ex.: voz metálica) 2400-3400Hz – pouca informação 3 bits por amostra
Codificação por Transformadas Idéia básica Transformar os dados para outro domínio matemático onde uma técnica de compressão seja melhor aplicada Ex.: Transformada de Fourier => transforma sinais no domínio do tempo para o domínio da frequência Deve existir uma transformada inversa Transformadas eficazes para redução de dados são: DCT – Discrete Cosine Transform (JPEG) FFT – Fast Fourier Transform (MPEG-áudio)
Quantização Vetorial Fluxo de dados é divido em blocos Constrói uma tabela (ou usa uma predefinida) contendo o conjunto de valores que mais aparecem (valores padrões) Para cada bloco, a tabela é consultada para achar o padrão mais parecido Então cada bloco é codificado com o índice do vetor O decodificador deve conhecer a mesma tabela e usa os índices para gerar uma aproximação do fluxo de dados original
Compressão de Texto Texto não tolera erros Compactação = Compressão sem perdas Classificação das técnicas de compactação: Técnicas que usam caracteres únicos como base X Técnicas que usam strings de caracteres como base Codificação estática X Codificação dinâmica
Compressão de Texto Técnicas que usam caracteres únicos como base Codificação por carreira Só usa se repetir no mínimo 4 vezes (caracter, símbolo (!), número de vezes) entrada: ABCCCCCCCCDEFGGG saída: ABC!4DEFGGG Codificação de Shannon-Fano Codificação aritmética Codificação de Huffman
Compressão de Texto Técnicas que usam strings de caracteres como base Codificação por carreira pode-se substituir sequências maiores que um requer que o tamanho da sequência seja codificado ou pode-se usar um caracter especial de fim (símbolo (!), número de vezes, seqüência, delimitador de fim ($)) entrada: UFYUGDUFHUFHUFHUFHUFHBFD saída: UFYUGD!5UFH$BFD Codificação de Lempel-Ziv-Welch
Compressão de Texto Codificação estática Exemplos: Tabelas de códigos são conhecidas a priori (padronizadas) Tabelas de códigos são enviadas junto com a seqüência codificada Exemplos: Codificação de Shannon-Fano Codificação aritmética Codificação de Huffman Codificação de Lempel-Ziv Codificação dinâmica Tabelas de códigos são calculadas dinamicamente no momento da decodificação Codificação de Lempel-Ziv-Welch Codificação de Huffman dinâmica