Material de Auxílio Didático
EA978 - Sistemas de informações gráficas
Primeiro semestre de 2003
2o Projeto
Atividade 1 - Quantização
Objetivo: Quantizar em dois tons (preto e branco) uma imagem em tons de cinza da cena do primeiro projeto usando a técnica de limiarização, dithering aleatório, dithering ordenado e difusão de erros.
Quantização de luminância por limiarização
Para a quantização de luminância por limiarização deverá ser primeiro calculado o histograma da imagem original. O histograma é utilizado para a escolha de um valor que separa de forma apropriada os tons mais claros e os tons mais escuros da imagem.
Para calcular o histograma utilize o seguinte esqueleto de código: hist.c. Esse programa deve ser adaptado com o código gerado no projeto anterior. O histograma da imagem é mostrado tanto na forma gráfica como em texto no console. A determinação do histograma é realizada através do comando glHistogram() disponível na versão 1.2 do OpenGL. Um exemplo de histograma calculado sobre uma imagem é mostrado a seguir. O histograma é mostrado em amarelo, sobreposto à imagem:
Histograma (em amarelo) e imagem em tons de cinza correspondente. Os valores da
intensidade mínima (0) e máxima (255) são mostrados no lado esquerdo e direito
da imagem, respectivamente.
Com base no histograma é possível escolher de forma mais precisa um limiar para o processo de limiarização. No histograma acima é possível notar que há um grande número de pixels com valor 0, isto é, um grande número de pixels pretos. Na figura acima esses pixels correspondem ao fundo da imagem. Com exceção desses pixels, são os tons médios que predominam na cena, conforme se observa no centro do histograma. Nesse caso, um limiar satisfatório para separar os tons altos dos tons baixos deverá ser escolhido provavelmente entre 100 e 130.
Uma vez escolhido o limiar, este deve ser utilizado no processo de limiarização proposto no seguinte esqueleto de código: threshold2.c
O resultado será semelhante ao mostrado abaixo:
Cena quantizada pelo método de limiarização (limiar de 128)
O limiar utilizado nessa tarefa pode ser utilizado nas tarefas seguintes.
Quantização de luminância por dithering aleatório
Use o seguinte esqueleto de código para implementar essa tarefa: randdith.c
No esqueleto de código dado, modifique as funções init(), display() e reshape() na parte indicada pelos comentários, de acordo com o código produzido no primeiro projeto.
A imagem de entrada e saída do algoritmo de quantização é armazenada no ponteiro frameBuf. Essa variável aponta para uma array de w*h bytes, onde w é a largura da imagem e h a altura. Cada byte é um valor entre 0 e 255 que descreve a luminância da imagem.
O resultado será semelhante ao mostrado abaixo:
Cena quantizada pelo método de dithering aleatório.
Quantização de luminância por dithering ordenado
Use o seguinte esqueleto de código para implementar essa tarefa: orddith.c
No esqueleto de código dado, modifique as funções init(), display() e reshape() na parte indicada pelos comentários, de acordo com o código produzido no primeiro projeto.
A imagem de entrada e saída do algoritmo de quantização é armazenada no ponteiro frameBuf. Essa variável aponta para uma array de w*h bytes, onde w é a largura da imagem e h a altura. Cada byte é um valor entre 0 e 255 que descreve a luminância da imagem.
O resultado será semelhante ao mostrado abaixo:
Cena quantizada pelo método de dithering ordenado usando uma matriz de
Bayer 4x4.
Quantização de luminância por difusão de erros
Para a implementação dessa tarefa deverá ser utilizado o mesmo limiar escolhido na tarefa de quantização por limiarização.
Use o seguinte esqueleto de código para implementar essa tarefa: errdiff.c
No esqueleto de código dado, altere o valor de THRESHOLD para o limiar escolhido na tarefa de quantização por limiarização e use esse valor durante a quantização por difusão de erro. Altere também as funções init(), display() e reshape() na parte indicada pelos comentários, de acordo com o código produzido no primeiro projeto.
A imagem de entrada do algoritmo de quantização é armazenada no ponteiro frameBuf. Essa variável aponta para uma array de w*h bytes, onde w é a largura da imagem e h a altura. Cada byte é um valor entre 0 e 255 que descreve a luminância da imagem. O resultado deve ser gravado em frameBuf2, que é um ponteiro para uma array do mesmo tamanho de frameBuf.
O resultado será semelhante ao mostrado abaixo:
Cena quantizada pelo método de difusão de erro (Floyd-Steinberg, limiar de 128)
Autor: Harlen Costa Batagelo (harlen@dca.fee.unicamp.br)