Imagens binárias - Embarcados
Este post faz parte da série Imagens Binárias. Leia também os outros posts da série:
Imagens binárias II
Youtube, Netflix, Flickr, Instagram, etc, estão entre os sites mais populares no mundo. Esses são exemplos concretos de quanto popular se tornou fotografar ou filmar. Com um mercado tão grande quanto esse, em pouco tempo aumentou-se em muito a qualidade das imagens e hoje quase todas as câmeras fotográficas são capazes de filmar e tirar foto com alta resolução e principalmente com alta definição de cores.
Contudo, há apenas alguns anos, isso não era a realidade. Câmeras menos potentes, internet com conexão discada, discos rígidos com menor capacidade de armazenamento, etc, não permitiam o uso de imagens com alta resolução e, por isso, era necessário otimizar e comprimir as imagens, diminuindo-se a sua resolução, resolução de cores ou ambos. Porém, diminuir-se a resolução das cores às vezes não era uma escolha e sim um requisito de projeto. Por exemplo, em impressão em preto e branco, apenas duas cores são usadas. Neste post iremos mostrar algumas técnicas usadas para transformar imagens coloridas em imagens binárias.
Sabe-se que com as três cores primárias, vermelho, verde e azul, pode-se criar as outras cores do espectro. No caso de imagens true colors, cada pixel é representado por 24 bits, 8 bits para cada cor. Com esses 8 bits, pode-se definir 256 tons para cada uma das três cores primárias. Combinando-se essas três cores, pode-se ter até 16.777.216 diferentes tons. O preço a se pagar por essa definição é a quantidade de bytes necessária para armazenar uma imagem. Se pegarmos, por exemplo, uma imagem true color VGA de 640×480 pixels, precisa-se de:
640 x 480 x 24 = 7372800 bits
ou 921,6 Kbytes para ser representada. Uma imagem full HD 1080×1920 precisaria de 6.22 Mbytes para ser representada.
Já uma imagem binária é uma imagem onde cada pixel é representado apenas por um bit, ou seja, um pixel pode ser ou preto ou branco. Pode-se notar facilmente que uma imagem binária exige 24 vezes menos bits para ser representada. Neste caso uma imagem VGA binária, precisa de apenas 38,4 Kbytes para ser representada. E uma imagem full HD apenas 259,2 Kbytes.
Para se criar uma imagem binária, primeiro é preciso transformar uma imagem colorida em uma imagem em tons de cinza. Uma imagem em tons de cinza é uma imagem onde cada pixel é representado pela intensidade da luz apenas. Normalmente usa-se 8 bits para se ter até 256 tons de cinza. A transformação é dada pela seguinte fórmula:
y = 0,2126*R + 0,7152*G + 0,0722*B
onde y é o valor da intensidade, R é o nível de vermelho, G é o nível de verde e B o nível de azul. O porquê desta fórmula está fora do escopo deste post, mas pode-se aprender mais no wikipédia. Abaixo o resultado da nossa foto em tom de cinza.
Figura 1 – Foto em tons de cinza
Binarização de imagens
Algoritmo 1: Threshold
Este é o método mais simples e intuitivo. Para cada pixel, verifica-se se ele possui um valor acima ou abaixo de um limite (threshold). Estando acima, define-se esse pixel com o valor 1, e estando abaixo, define-se o valor como 0.
Figura 2 – Threshold
Apesar deste algoritmo ser simples e rápido, ele produz péssimos resultados.
Algoritmo 2: Ordered dithering
Neste método usa-se uma matriz para criar um erro aleatório na quantização dos pixels. Normalmente usa-se matrizes de Bayer, porém pode-se usar qualquer outra matriz. A vantagem desse algoritmo é a velocidade pois trata-se a imagem em blocos de pixels, definido pelo tamanho da matriz. Na imagem de exemplo usamos uma matriz de Bayer 8×8.
Figura 3 – Ordered dithering
Algoritmo 3: Error difusion
No nosso exemplo usaremos o algoritmo de Floyd–Steinberg, o qual tenta difundir o erro do pixel com os 4 pixels vizinhos. A difusão de erro do pixel é dividida nas seguintes proporções:
direita: 7/16
baixo-esquerda: 3/16
baixo: 5/16
baixo-direita: 1/16
Nota-se uma melhora na qualidade da imagem comparada às técnicas anteriores ao custo de processamento maior.
Figura 4 – Error difusion
Pode-se notar que, apesar de parecer simples, existe toda uma teoria para conseguir criar imagens binárias sem que se perca os seus detalhes. Vimos que usando-se a técnica mais simples e intuitiva (threshold) não se consegue bons resultados. Como referência este site mostra 11 diferentes algoritmos usados para binarizar imagens. No próximo post iremos implementar esses 3 algoritmos na prática usando algumas das ferramentas que já instalamos anteriormente.
[1] http://en.wikipedia.org/wiki/Grayscale [2] http://en.wikipedia.org/wiki/Ordered_dithering [3] https://en.wikipedia.org/wiki/Dither [4] http://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering [5] http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/