6 Armazenamento

Na grande maioria dos casos em que realizamos o processamento de imagens digitais, estamos trabalhando com dados armazenados na memória RAM do computador, esta é uma consequência da evolução tecnológica, onde atualmente a maioria dos computadores possuem uma grande quantidade de memoria RAM, na ordem de Gigabytes . A exceção está no processamento de imagens de resolução extrema, como é o caso de imagens em gigapixels. Porém quando precisamos salvar ou armazenar uma imagem, ainda é necessário transferir os dados da memoria volátil (memoria RAM) para alguma unidade de armazenamento não volátil como, por exemplo, o disco rígido.

Recorte de uma imagem em gigapixel. Recorte da imagem do polo norte lunar capturada por uma sonda lunar pela NASA. O mosaico original possui aproximadamente 867 bilhões de pixels e ocupa cerca de 950 Gigabytes (comprimidos). Fonte: [NASA](http://lroc.sese.asu.edu/posts/gigapan)

Figura 6.1: Recorte de uma imagem em gigapixel. Recorte da imagem do polo norte lunar capturada por uma sonda lunar pela NASA. O mosaico original possui aproximadamente 867 bilhões de pixels e ocupa cerca de 950 Gigabytes (comprimidos). Fonte: NASA

Existem uma infinidade de formatos de imagens digitais, desde os mais comuns para armazenamento de fotografias, gráficos, artes-vetoriais, até formatos para aplicações específicas, como equipamentos médicos, imagens 3D e imagens multi-resolução.

Os formatos de imagens digitais apresentam características distintas na capacidade de representar sistemas de cor, no uso e implementação de algoritmos de compressão e na estrutura de armazenamento dos dados.

Como vimos anteriormente, no formato matricial o número de pixels (resolução espacial) influencia diretamente a quantidade de informação necessária para armazenar uma imagem. Esse número não pode ser desconsiderado, ja que uma imagem aumenta consideravelmente de acordo com sua resolução. Por exemplo, uma imagem no formato de HDTV 720p de 1280×720 pixels tem um total de 921.600 pixels, ja um formato HDTV 1080p de 1920×1080 pixels tem um total de 2.073.600 pixels. Para um formato moderno, como a resolução de TVs 4K, teremos mais de 8 milhões de pixels. Ou seja, um aumento bastante expressivo.

Como podemos perceber, a resolução espacial influencia bastante no tamanho do arquivo final ao ser armazenado. Uma característica importante diretamente ligada a resolução e que deve ser levada em consideração é o formato utilizado para armazenar um pixel. Características da imagem influenciam nesse aspecto, tal como a quantidade de cores o sistema de cor utilizado e o número de bits por cor.

Para um sistema RGB, teremos 3 canais de cores. Cada componente é quantizada por um determinado número de bits. O mais comum é a utilização de 8 bits por cor. Porém, para algumas aplicações científicas não é raro termos 32 bits para cada componente.

Para o sistema utilizando 8 bits, temos 28=256 possibilidades de valores para cada pixel, normalmente mapeadas em inteiros de 0 a 255, como já vimos nos capítulos anteriores. Com essa quantidade de valores, para 3 canais de cores temos uma quantidade equivalente a 28×28×28=224=16.777.216 possíveis valores de cores. Esse formato de representação de um pixel é chamado de True Color. Nesse formato, utilizamos 24 bits para armazenamento de cada pixels.

É possível adicionar um canal de transparência, normalmente chamada de camada alfa. Esse canal pode ser mais simplista, armazenando apenas uma máscara que indica um estado binário que pode ser transparente ou opaco. Nesse caso apenas 1 bit é necessário. Porém a maioria dos formatos que possuem esse recurso utilizam um canal de 8 bits, onde o valor mínimo 0 representa uma posição totalmente transparente, o valor máximo 255 representa totalmente opaco e os valores intermediários representam os níveis variáveis de transparência. Esse formato também é chamado de RGBA8, pois utiliza 4 canais (RGBA) com 8 bits cada.

Nessa representação é comum interpretarmos o valor binário utilizando uma estrutura composta de inteiros sem sinal de 8 bits (unsigned int 8 , ou uint8 ). O formato RGBA8 é interessante pois utiliza 32 bits para cada pixel, o que condiz com a maioria das arquiteturas utilizadas nas CPUs e GPUs e consequentemente com as instruções e registradores dos mesmos.

Exercício

Considere a linha abaixo como os dados de uma imagem utilizando 8 bits por canal, com pixel utilizando o formato RGB.

1,1,1,1,1,1,1,1 0,0,0,0,1,1,0,1 0,0,0,0,0,0,0,0 0,1,1,1,1,1,1,1 0,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1 0,1,0,0,0,0,0,0 0,0,0,0,1,0,0,0 1,1,0,0,0,0,0,0

Os bits foram separados em grupos de 8 bits para facilitar a leitura.

Converta os 3 pixels acima para um formato legível do tipo:

Pixel 1 (200,0,34),
Pixel 2 (100,3,13),
Pixel 3 (8, 65, 170)

Você pode utilizar python ou realizar a conversão manualmente.

Armazenar os dados brutos de uma imagem é algo que raramente acontece. Isto se deve pela quantidade de memória necessário para isso. Uma imagem com resolução de 1920×1080 armazenada puramente em RGBA8, ocuparia 1920×1080×32=66.355.200 bits, ou seja, aproximadamente 8.3MB. Esta é uma grande quantia, considerando que a mesma imagem em um formato padrão da internet, como o JPEG, ocuparia na ordem de grandeza de kilobytes. Se esse arquivo fosse armazenado utilizando RGBA e 32 bits por canal, ele ocuparia cerca de 33 MB.

A maioria dos formatos de imagem digital apresenta alguma forma de compressão de dados. Existem muitos algoritmos diferentes de compressão em vários níveis de redundância. Na próxima sessão deste capítulo iremos explorar formas de compressão de dados.