Você está na página 1de 9

UFRGS - PPGEE - 2012 LAB09

Processamento Digital de Sinais (DSP) - Laboratório 09 - Representação de


Números e Quantização de formas de onda
Material Desenvolvido pelo Prof. Charles A. Bouman e traduzido (com autorização) pelo
Prof. Valner Brusamarello
Departamento de Engenharia Elétrica, Universidade Federal do Rio Grande do Sul
brusamarello.valner@gmail.com

1 Introdução
Este labortório apresenta dois importantes conceitos de sinais digitais. A primeira secção
discute como os números são armazenados em memória. Números podem ser de ponto fixo
ou pnto flutuante. É coerente que decimais e números que podem ter faixas muito largas
de valores utilizem o sistema de ponto flutuante ou floating point. O segundo assunto sobre
armazenamento numérico é a quantização. Todos os sinais anaçógicos que são processados no
computador precisam ser quantizados. Vamos examinar os erros que surgem nessa operação
e determinar como diferentes nı́veis de quantização afetam a qualidade do sinal. Vamos
estudar dois tipos de quantizadores. O quantizador uniforme e o quantizador max, o qual
minimiza o erro médio quadrático entre o sinal original e o sinal quantizado.

2 Revisão da Representação de Números


Os computadores podem representar inteiros e decimais. Esses dois números são armazena-
dos de maneira bastante diferente na memória. Inteiros como (27, 0, −986) são geralmente
armazenados na forma de ponto fixo enquanto decimais como (12.34, −0.98) na maioria das
vezes utilizam o formato de ponto flutuante. A maioria das representações de inteiros uti-
lizam quatro bytes de memória; valores aramazenados no formato de ponto flutuante utilizam
geralmente oito bytes.
Existem diferentes convenções para codificar números binários porque existem diferentes
maneiras de representar um número negativo. Podemos citar três tipos de formato de ponto
fixo que acomodam inteiros negativos: sign-magnitude, complemento de um e complemento
de dois. Nesses três formatos o primeiro bit representa o sinal do número: 0 para positivo
e 1 para negativo. Para números positivos a magnitude simplesmente segue o primeiro bit.
Os números negativos são manipulados de forma diferente em cada formato.
Também existe um tipo de dado denominado unsigned, que é usado quando sabe-se que
a variável não assume valores negativos. Isso permite uma faixa maior de números possı́veis,
uma vez que um bit não é desperdiçado com o sinal negativo.

2.1 Representação sign-magnitude


A notação sign-magnitude consiste na maneira mais simples de representar números nega-
tivos. A magnitude do número negativo segue o primeiro bit. Se um inteiro foi armazenado
UFRGS - PPGEE - 2012 LAB09

como um byte, a faixa de valores possı́veis é [−127, 127].


O valor +27 pode ser representado como: 0 0 0 1 1 0 1 1
O valor −27 pode ser representado como: 1 0 0 1 1 0 1 1

2.2 Complemento de um
Para representar um número negativo é calculado o complemento de cada um dos bits do
número positivo. O número positivo 27 na forma de complento de um é escrito como:

0 0 0 1 1 0 1 1

e o valor −27 pode ser representado como:

1 1 1 0 0 1 0 0

2.3 Complemento de dois


O problema com as notações anteriores é que dois valores diferentes representam zero. A
notação em complemento de dois é uma revisão do complemento de um. Para formar um
número negativo o número positivo é subtraı́do de um certo número binário. Esse número
tem um one no bit mais significativo (MSB), seguido por zeros (tantos zeros quanto o número
de bits da representação do número). Se o número 27 fosse representado por um inteiro de
oito bits, então −27 seria representado da seguinte forma:
1 0 0 0 0 0 0 0 0
−0 0 0 1 1 0 1 1
=1 1 1 0 0 1 0 1
Note que esse resultado é um mais o complemento de 1 da representação de −27. Assim,
a segunda representação de 0 é:
1 0 0 0 0 0 0 0
esse valor é igual a −128 na notação de complemento de dois.
1 0 0 0 0 0 0 0 0
−1 0 0 0 0 0 0 0
=1 0 0 0 0 0 0 0
O valor representado aqui é −128; sabemos que é negativo porque o resultado tem 1 no
MSB. O complemento de dois é utilizado porque ele pode representar um número negativo
extra. Mais importante, se a soma de uma série de números em complemento de dois dentro
de uma faixa, resultar em overflow durante a soma, isso não afetará o resultado final! A
faixa de um número de 8 bits em complemento de dois é [-128,127].

2.4 Ponto Flutuante


A notação em ponto flutuante é usada geralmente para representar uma faixa muito larga
de números. O fato interessante é que a resolução é variável: ela diminui com o aumento
UFRGS - PPGEE - 2012 LAB09

da magnitude do número. Nos exemplos de ponto fixo mostrados anteriormente, a resolução


estava fixa em 1. É possı́vel representar números decimais com notação de ponto fixo,
mas para uma palavra de comprimento fixo qualquer incremento na resolução causa um
decremento da faixa de valores representados.
Um número em ponto flutuante, F, possui duas partes: a mantissa, M, e um expoente, E.

F = M ∗ 2E

A mantissa é uma fração com sinal, que possui uma potência de dois no denominador.
O expoente é um inteiro com sinal, que representa a potência de dois que a mantissa deve
ser multiplicada. Esses números com sinais podem ser representados com qualquer um dos
três formatos de números de ponto fixo. A IEEE possui um padrão para ponto flutuante
(IEEE 754). Para um número de 32 bits, o primeiro bit é o sinal da mantissa. O expoente
os utiliza os próximos oito bits (o primeiro para o sinal e os 7 restantes para a quantidade),
e a mantissa é armazenada nos 23 bits resntantes. A faixa total de valores para esse número
é [−1.18 ∗ 10−38 , 3.4038 ].
Para adicionar dois números em ponto flutuante, os expoentes devem ser iguais. Se os
expoentes forem diferentes a mantissa é ajustada até que os expoentes sejam corrigidos. Se
um número muito pequeno é adicionado a um número muito grande, o resultado pode ser
igual ao número muito grande. Por exemplo, se 0.15600...0 ∗ 230 é adicionado a 0, 62500...0 ∗
2−3 , o segundo número seria convertido para 0.0000...0 ∗ 230 antes da adição. Uma vez que
a mantissa consegue armazenar apenas 23 números binários, os dı́gitos decimais 625 seriam
perdidos na conversão. Em resumo, o segundo número é arredondado para zero. Para a
multiplicação, os dois expoentes são adicionados e a mantissas multiplicadas.

3 Quantização
3.1 Introdução
Quantização é o ato de aproximar o valor de um sinal ou quantidade para certos nı́veis
discretos. Por exemplo, escalas digitais podem arredondar peso para a grama mais próxima
(na verdade, se estivermos falando sobre peso trata-se de força e portanto gramas-força;
caso contrário se for massa gramas). Tensões analógicas em um sistema de controle pode ser
arredondadas para o valor mais próximo de tensão antes de entrar no sistema controle digital.
Geralmente todos os números necessitam ser quantizados antes de serem representados no
computador.
Imagens digitais também são quantizadas. Os nı́veis de cinza em uma fotografia preta
e branca precisam ser quantizados para armazenar a imagem no computador. Usualmente
é atribuı́do um valor inteiro entre 0 e 255 (tipicamente) para o brilho da fotografia em
cada pixel, onde 0 corresponde ao preto e 255 ao branco. Um vez que um número de 8
bits pode representar até 256 diferentes valores, a imagem é denominada de ’imagem em
escala de 8 bits de cinza’. Uma imagem que é quantizada para apenas 1 bit por pixel (pode
UFRGS - PPGEE - 2012 LAB09

assumir apenas pixels em branco ou preto) é denominada de imagem de meio tom. Muitas
impressoras funcionam colocando, ou não colocando, uma região de tinta colorida em cada
ponto no papel. Para que isso seja adequado, a imagem deve passar por um processo de
’meio tom’ antes ser impressa.
A quantização pode ser pensada como um mapeamento funcional y = f (x) de um valor
real de entrada para um valor discreto de saı́da. Um exemplo de uma função de quantização
é mostrado na Figura 1, onde o eixo x é o valor de entrada e o eixo y é o valor de saı́da
quantizado.

3.2 Quantização e Compressão


A quantização é algumas vezes utilizada na compressão. Como exemplo, suponha que nós
temos uma imagem digital que é representada por 8 nı́veis de cinza:
[0 31 63 95 159 191 223 255].
Para armazenar diretamente cada um dos valores da imagem nós precisamos no mı́nimo 8
bits para cada pixel, uma vez que os valores estão dentro de uma faixa de 0 a 255. Entretanto,
como a imagem tem apenas oito valores diferentes, nós podemos atribuir um código de três
bits para represntar cada piel: [000 001 ... 111]. Então, ao invés de armazenar os nı́veis
de cinza, podemos armazenar apenas um código de três bits para cada pixel. Uma tabela,
possivelmnte armazenada no inı́cio do arquivo, poderia ser armazenada para a decodificação
do arquivo. Esse processo reduz o custo de uma imagem consideravelmente: menor espaço de
memória para armazenamento e uma banda mais estrita pode ser utilizada para a transmissão
dessa imagem (ou seja, o seu download será mais rápido). Na prática, existem métodos muito
mis sofisticados de compressão de imagens que dependem da quantização.

3.3 Quantização de Imagens


Faça o download do arquivo ’fountainbw.tif’. Esta é uma imagem de 8 bits de nı́veis de
cinza. Vamos agora investigar o que acontece se quantizarmos a imagem com menos bits por
pixel (b/pol). Carregue a imagem no matlab e mostre a mesma usando a sequinte sequência
de comandos:
y=imread(’fountainbw.tif’);
image(y);
colormap(gray(256));
axis(’image’);
O array da imagem será inicialmente do tipo uint8, assim você precisará converter a ma-
triz da imagem para o tipo double antes de executar os cálculos. Use o camando z=double(y).
Existe um meio fácil de quantizar o sinal uniformemente. Façamos:
M ax(X)−M in(X)
∆= N −1

onde X é o sinal a ser quantizado, e N é o número de nı́veis de quantização. A fim de forçar


os dados a obterem um passo de quantização uniforme de ∆,
UFRGS - PPGEE - 2012 LAB09

Figure 3.1: Relação de entrada-saı́da de um quantizador uniforme de 7 nı́veis

• Subtrair M in(X) dos dados e dividir o resultado por ∆.

• Arredondar os dados para o inteiro mais próximo.

• Multiplicar os dados arredondados por ∆ e adicionar M in(X) para converter os dados


novamente em sua escala original.

Escreva uma função matlab Y=Uquant(X,N) que faz a quantização uniforme de um array
de entrada X (vetor ou matriz) para N nı́veis discretos. Utilize essa função para quantizar
a imagem fountainbw.tif para 7 b/pel, 6,5,4,3,2,1 b/pel e observe as imagens de saı́da.

• Descreva os erros que surgem com a diminuição do número de bits.

• Tente identificar o número de b/pel no qual a imagem notoriamente deteriora.

• Compare as imagens em relação a original

3.4 Quantização de Áudio


Se um sinal de áudio necessita ser codificado, para compressão ou para transmissão digital ele
precisa passar por alguma forma de quantização. É comum utilizar uma técnica denominada
de ’quantização vetorial’ para executar essa tarefa. Porém essa técnica deve ser adaptada
para cada aplicação e por isso não será abordada. Nesse exercı́cio vamos observar o efeito
da quantizaçao uniforme em dois sinais de áudio.
UFRGS - PPGEE - 2012 LAB09

Primeiramente faça o download dos arquivos speech.au e music.au. Utilize a sua função
Uquant para quantizar os sinais para 7,4,2 e 1 bits/amostra. Escute o sinal original e os sinais
quantizados e reponda as seguintes questões:

• Descreva as mudanças de qualidade nos sinais com a redução do número de bits por
amostra.

• Existe um ponto, no qual a qualidade dos sinais é deteriorada drasticamente?

• Qual dos sinais tem a sua qualidade deteriorada primeiro com a diminuição do número
de nı́veis?

• Você acredita que 4 bits por amostra é aceitável para sistemas de telefonia? ... 2 bits
por amostra?

Utilize o comando subplot para plotar os quatro sinais do sinal speech.au de na faixa
de ı́ndices 7201:7400. Repita esse procedimento para o sinal music.au. Faça as observações
nessas figuras.

3.4.1 Análise do Erro


Como observamos, o procedimento de quantização produz erros no sinal. Os métodos de
análise de erro mais efetivos são probabilı́sticos. Para aplicar esses métodos é necessário
ter um entendimento claro das propriedades estatı́sticas do erro do sinal. Algumas questões
devem ser esclarecidas, como: o erro do sinal é um ruı́do branco? Podemos assumir que ele
não é correlacionado com o sinal quantizado? Veremos que podemos assumir o erro como
um ruı́do branco e descorrelacionado, se os intervalos de quantização são pequenos quando
comparados com a variação do sinal de amostra para a amostra.
Se o sinal original é X, e o sinal quantizado é Y , o erro do sinal é definido por:

E =X −Y

Calcule o erro do sinal para o sinal speech.au quantizado em 7,4,2 e 1 bit/amostra.


Quando o espaçamento, ∆, entre os nı́veis de quantização é suficientemente pequeno, um
modelo estatı́stico comum para o erro é uma distribuição uniforme de − ∆2 a ∆2 . Utilize o
comando hist(E,20) para gerar histogramas com 20 espaçamentos para cada um dos quatro
sinais. Utilize o comando subplot para colocar as figuras em um mesmo gráfico. Observe
como o número de nı́veis de quantização parece afetar a forma do histograma. Explique
porque os histogramas de erros obtidos podem não ser uniformes.
Em seguida vamos examinar as propriedades de correlação do sinal de erro. Primeiro
calcule e plote uma estimativa de uma função autocorrelação para cada um dos quatro sinais
de erro usando os seguintes comandos:

[r,lags]=xcorr(E,200,’umbiased’);
plot(lags,r)
UFRGS - PPGEE - 2012 LAB09

Agora calcule e plote uma estimativa da função de correlação cruzada entre o sinal
speech.au quantizado Y e cada sinal de erro E usando:
[c,lags]=xcorr(E,Y,200,’umbiased’);
plot(lags,c)
• A correlação é influnciada pelo número de nı́veis de quantização? As amostras no sinal
de erro parecem estar correlacionadas umas com as outras?
• O número de nı́veis de quantização influencia a correlação cruzada?

3.4.2 Relação Sinal Ruı́do


Uma maneira de medir a qualidade do sinal é pela relação das potências de sinal-ruı́do
(PSNR - Power Signal-to-Noise Ratio). A mesma é definida pela relação da potência do
sinal quantizado pela potência do ruı́do:
PY
P SN R = PE

Nessa expressão, o ruı́do é o sinal de erro E. Geralmente , isso significa que um alto
P SN R implica em um sinal menos ruidoso.
A potência do sinal amostrado x(n) é definida por:
Px = L1 Ln=1 x2 (n)
P

onde L é o comprimento de x(n). Calcule o PSNR para os quatro sinais speech.au


quantizados da secção anterior.
Um gráfico denominado de rate-distortion curve (curva de taxa de distorção) é usualmente
utilizado. Essa curva plota a distorção do sinal versus taxa de bits. Aqui, nós podemos medir
1
a distorção por P SN R
, e determinar a taxa de bits do número de nı́veis de quantização e taxa
de amostragem. Por exemplo, se a taxa de amostragem é de 8000 amostras por segundo, e
nós estamos utilizando 7 bits/amostra, a taxa de bits é de 56 kilobits por segundo (kbps).
Assumindo que o sinal é amostrado em 8 kHz, plote a curva de taxa de distorção us-
1
ando P SN R
como medida da distorção. Gere esta curva calculando a PSNR para 7,6,5,...,1
bits/amostra. Faça os eixos do gráfico em termos de distorção e taxa de bits.

3.5 Quantizador Max


Nessa secção vamos investigar um tipo de quantizador diferente que produz menos ruı́do
para um número fixo de nı́veis de quantização. Como exemplo considere que a faixa de
entrada para nosso sinal é [−1, 1], mas a maioria do sinal de entrada tem os seus valores
entre [−0.2, 0.2]. Se nós colocarmos mais nı́veis de quantização próximo de zero podemos
diminuir o erro médio devido a quantização.
Uma medida comum de erro de quantização é o erro médio quadrado (potência do ruı́do).
O quantizador max é projetado para minimizar o erro médio quadrado para um dado con-
junto de dados. Vamos estudar como o quantizador max funciona e comparar o seu desem-
penho com com o do quantizador uniforme que foi utilizado nas secções anteriores.
UFRGS - PPGEE - 2012 LAB09

Figure 3.2: Quantizador Max de cinco nı́veis para um sinal com distribuição gaussiana

3.5.1 Demonstração
O quantizador max determina os nı́veis de quantização baseado na função densidade de
probabilidade do conjunto de dados f (x), e o número de nı́veis desejados N . Ele minimiza
o erro médio quadrado entre o sinal original e o sinal quantizado:
N Z
X xk+1
= (qk − x)2 f (x)dx (3.1)
k=1 xk

onde qk é o k esimo nı́vel de quantização e xk é o limite inferior para qk . O erro  depende de


qk e xk . Note que para a distribuição gaussiana, x1 = −∞ e xN +1 = ∞. Para minimizar 
∂
em relação a qk , precisamos fazer ∂x k
= 0 e resolver para qk :
R xk+1
x
xf (x)dx
qk = R kxk+1 (3.2)
xk
f (x)dx
∂
Nós ainda precisamos dos limites de quantização, xk . Resolvendo ∂xk
= 0 resulta em:
qk−1 +qk
xk = 2

Isso significa que cada limite não infinito é exatamente a metade de dois nı́veis adjacentes
de quantização. e que cada nı́vel de quantização está no centróide de sua região. A Figura 2
mostra um quantizador de cinco nı́veis para um sinal com distribuição gaussiana. Note que
os nı́veis estão próximos nas regiões de probabilidade elevada.

3.5.2 Implementação, Análise de erro e comparação


Vamos usar o matlab para calcular um quantizador ótimo e comparar o seu desempenho com
o quantizador uniforme. Como quase nunca sabemos a função densidade de probabilidades
dos dados que serão aplicados ao quantizador não podemos esar equação (3.2) para calcular
os nı́veis ótimos de quantização. Portanto, um procedimento de otimização numérica é usado
em um conjunto de dados para treinamento para calcular os nı́veis de quantização e limites
que produzem o menor erro possı́vel para aquele conjunto de dados.
UFRGS - PPGEE - 2012 LAB09

O matlab possui uma função chamada lloyds que faz essa otimização. A sua sintaxe é:

[partition, codebook] = lloyds(trainingset, initialcodebook)

Essa função requer duas entradas. A primeira é o conjunto de dados de treinamento, do


qual será estimada a função de densidade de probabilidade. A segunda é um vetor contendo
um ’chute’ inicial dos nı́veis de quantização ótimos. Ela retorna os limites ótimos calculados
(partition) e os nı́veis de quantização (codebook).
Uma vez que esse algoritmo minimiza o erro em relação aos nı́veis de quantização, é
necessário escolher um ’chute’ inicial adequado para codebook. Se esse valor inicial está
significativamente distante da solução ótima, é possı́vel que a otimização fique presa em
um mı́nimo local. Para fazer um bom ’chute inicial’ nós podemos primeiramente estimar a
forma da função de densidade de probabilidades do conjunto de treinamento utilizando um
histograma. A idéia é dividir o histograma em áreas iguais e escolher nı́veis de quantização
no centro de cada um dos segmentos.
Primeiramente plote um histograma de 40-bin (40 espaçamentos) do sinal speech.au
usando hist(speech,40), e faça um ’chute’ inicial dos quatro nı́veis ótimos de nı́veis de
quantização. Depois de imprimir os gráficos utilize a função lloyds para calcular os quatro
nı́veis ótimos para codebook usando speech.au como o conjunto de treinamento.
Uma vez que o codebook ótimo é obtido, utilize os vetores codebook e partition para
quantizar o sinal speech. Então calcule o sinal de erro e a PSNR. Compare o PSNR e a
qualidade do som sinais quantizados com o método apresentado na secção anterior.

Você também pode gostar