Pergunta

Eu tenho um aplicativo incorporado, onde um scanner de imagem envia um fluxo de pixels de 16 bits que são posteriormente montados em uma imagem em escala de cinza. Como eu preciso salvar esses dados localmente e encaminhá -los para uma interface de rede, gostaria de comprimir o fluxo de dados para reduzir o espaço de armazenamento e a largura de banda de rede necessários.

Existe um algoritmo simples que eu possa usar para comprimir sem perdas os dados do pixel?

Primeiro pensei em calcular a diferença entre dois pixels consecutivos e depois codificar essa diferença com um código Huffman. Infelizmente, os pixels são quantidades de 16 bits não assinadas, portanto a diferença pode estar em qualquer lugar no intervalo -65535 .. +65535, o que leva a comprimentos potencialmente enormes da palavra de código. Se algumas palavras de código realmente longas ocorrerem seguidas, eu encontrarei problemas de estouro de buffer.

Atualização: minha plataforma é um FPGA

Foi útil?

Solução

Png Fornece compactação de imagem gratuita, de código aberto e sem perdas em um formato padrão usando ferramentas padrão. PNG usa zlib como parte de sua compressão. Há também um libpng. A menos que sua plataforma seja muito Incomum, não deve ser difícil portar esse código para ele.

Outras dicas

Quantos recursos você tem disponível em sua plataforma incorporada?

Você poderia portar zlib E a compactação gzip? Mesmo com recursos limitados, você deve poder portar algo como LZ77 ou LZ88.

Há uma grande variedade de bibliotecas de compressão de imagem disponíveis. Por exemplo, esta página Liste nada além de bibliotecas/kits de ferramentas para imagens PNG. Qual formato/biblioteca funciona melhor para você provavelmente dependerá das restrições de recursos específicas em que está trabalhando (em particular, se o seu sistema incorporado pode ou não fazer aritmética de ponto flutuante).

O objetivo da compactação sem perdas é poder prever o próximo pixel com base em pixels anteriores e, em seguida, codificar a diferença entre sua previsão e o valor real do pixel. É isso que você pensou inicial a fazer, mas você estava usando apenas o pixel anterior e fazendo a previsão de que o próximo pixel seria o mesmo.

Lembre -se de que, se você tiver todos os pixels anteriores, terá mais informações relevantes do que apenas o pixel anterior. Ou seja, se você estiver tentando prever o valor de x, use os pixels O:

..Ooo ...
..BOI

Além disso, você não gostaria de usar o pixel anterior, B, no fluxo para prever X na seguinte situação:

Oo ... b <- fim da linha
X <- Início da próxima linha

Em vez disso, você faria sua base de previsão no sistema operacional.

Como você precisa?
Se este é um scanner real, há um limite para a largura de banda/resolução, portanto, mesmo que possa enviar valores +/- 64k, pode não ser físico para os pixels adjacentes terem uma diferença de mais do que 8 bits.

Nesse caso, você pode fazer um valor de pixel inicial para cada linha e, em seguida, fazer diferenças entre cada pixel.

Isso manchará os picos, mas pode ser que os picos mais do que os n'bits sejam ruído de qualquer maneira.

Um bom híbrido LZ77/RLE com sinos e wwhistles pode obter uma compressão maravilhosa que é bastante rápida em descomprimir. Eles também serão compressores maiores e mais ruins em arquivos menores devido à falta de sobrecarga da biblioteca. Para uma boa, mas a implicação da GPLD disso, confira Pucrunch

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top