Compressão rápida e sem perdas de um fluxo de vídeo

15

Eu tenho um vídeo vindo de uma câmera estacionária. Tanto a resolução quanto o FPS são bastante altos. Os dados que recebo estão no formato Bayer e usam 10 bits por pixel. Como não há nenhum tipo de dados de 10 bits na minha plataforma, os dados originais são armazenados na memória usando palavras de 16 bits. Quero implementar algum tipo de compactação sem perdas dos dados antes de transmiti-los pela rede.

  • A câmera não se move, então partes grandes de quadros consecutivos são quase idêntico - mas ainda não completamente, devido ao inevitável ruído (denoising não é uma opção, como é suposto ser sem perdas e não deve "perder" nem mesmo o ruído).
  • Por causa do alto FPS, até mesmo as partes que mudam não mudam muito entre dois quadros consecutivos.
  • No entanto, parece que a câmera também balança um pouco. Muito pouco, mas ainda assim, mesmo os objetos estacionários não são completamente assim no espaço da imagem.
  • A compressão tem que ser feita na hora, então eu não consigo reunir muito de quadros e comprimi-los todos juntos, mas eu posso olhar 1 quadro de volta e usá-lo como referência.

Com base no exposto acima, meu primeiro pensamento foi o bit-pack dos dados, para que esses 6 bits redundantes não sejam desperdiçados em cada palavra. No entanto, pensei que, se eu usasse alguma codificação de entropia (por exemplo, Huffman etc.), essa redundância seria automaticamente levada em conta, portanto, nenhuma embalagem extra é necessária. Então fiz o seguinte:

  • Tomou a diferença binária entre dois quadros consecutivos. O original o intervalo de dados foi de 0 a 1023 (por exemplo, 10 bits não assinados). Dados de diferença torna-se assinado e o intervalo aumenta para -1023 ~ 1023, mas os dados variação (ou qual é o termo matemático correto) torna-se muito menos do que nos dados originais, de fato, a maioria dos valores são, não Surpreendentemente, perto de zero.
  • Arroz aplicado codifica a diferença. Pelo que entendi, parece uma boa escolha para conjuntos de dados de pequeno número numérico valores.

Isso me dá cerca de 60% de redução no tamanho para quadros de 1280x720, e meu sistema de teste (Linux no VirtualBox em um único núcleo) pode fazer ~ 40 dessas compactações por segundo (sem muita otimização). Não é ótimo, mas razoável, eu acho (ou é?).

Existem maneiras melhores? Algum erro comum que cometi? Quaisquer passos gerais que perdi? Quadros de resolução mais alta podem ser usados mais tarde - devo esperar melhores taxas de compactação para tamanhos de quadros maiores?

UPD .:

Como os números negativos não têm zeros à esquerda, apliquei codificação em zigue-zague após a diferença binária e antes da supressão de Arroz / zero .

    
por Headcrab 04.07.2016 / 07:17
fonte

2 respostas

4

Você tem previsão temporal, mas não espacial. Para uma melhor compressão ao custo da velocidade, você deve ser capaz de usar os pixels acima e à esquerda do pixel atual no quadro atual como preditores, bem como o pixel no mesmo local no quadro anterior. O motivo de apenas olhar para cima e para a esquerda é o mesmo que o motivo de apenas olhar para o quadro anterior; você quer confiar somente nos dados que você já decodificou e limitar o quanto você precisa manter por perto.

Códigos de arroz provavelmente são um bom compromisso entre eficiência e velocidade, mas um código estático de Huffman (pré-computado por você em uma amostra de dados de vídeo) pode ser mais eficiente e igualmente rápido.

Quanto à velocidade, certifique-se de que seu código esteja obtendo vetorizado - usando os sinalizadores de compilador e os padrões de código corretos para permitir que o compilador auto-vetorize, ou escrevendo manualmente o código para usar vetor intrínsecos ou assembly.

Finalmente, está caindo para 8 bits por pixel, uma possibilidade? Obviamente, isso está deixando o reino de "sem perdas", mas não apenas reduziria o tamanho da sua saída compactada, mas também, com o código vetorizado, possivelmente aumentaria sua taxa de transferência em até 2x.

    
por 04.07.2016 / 11:30
fonte
0

Você provavelmente é mais bem atendido usando implementações existentes de compactação e descompactação. Sua implementação existente parece similar ao codec HuffYUV , então pode valer a pena tentar ver se funciona bem o suficiente para você .

    
por 05.07.2016 / 09:41
fonte