Sur la volée de compression d'image sans perte
-
26-09-2019 - |
Question
I ont une application embarquée, où un dispositif de balayage d'image envoie un flux de pixels de 16 bits qui sont ensuite assemblées en une image en niveaux de gris. Comme je l'ai besoin à la fois sauver ces données au niveau local et le transmettre à une interface réseau, je voudrais compresser le flux de données afin de réduire l'espace de stockage nécessaire et la bande passante réseau.
Y at-il un algorithme simple que je peux utiliser pour compresser sans perte les données de pixels?
I a d'abord pensé à calculer la différence entre deux pixels consécutifs et codant pour cette différence avec un code de Huffman. Malheureusement, les pixels sont des quantités 16 bits non signés de sorte que la différence peut se situer dans la gamme -65535 .. 65535 ce qui conduit à des longueurs de mots de code potentiellement énormes. Si quelques mots de code très longs se produisent dans une rangée, je vais courir dans des problèmes de débordement de la mémoire tampon.
Mise à jour: ma plate-forme est un FPGA
La solution
PNG fournit gratuitement, open-source, compression d'image sans perte dans un format standard en utilisant la norme outils. PNG utilise zlib
dans le cadre de sa compression. Il y a aussi un libpng
. À moins que votre plate-forme est très inhabituel, il ne devrait pas être difficile de porter ce code à lui.
Autres conseils
Il existe une grande variété de bibliothèques de compression d'images disponibles. Par exemple, cette page de listes de rien, mais les bibliothèques / boîtes à outils pour les images PNG. Quel format / bibliothèque qui fonctionne le mieux pour vous le plus probable dépendra des contraintes de ressources particulières que vous travaillez sous (en particulier, que ce soit ou non votre système embarqué peut effectuer des opérations arithmétiques à virgule flottante).
Le but avec compression sans perte est d'être en mesure de prédire le pixel suivant en fonction des pixels précédents, et pour coder la différence entre votre prédiction et la valeur réelle du pixel. C'est ce que vous avez pensé initiale à le faire, mais vous ne l'utilisait le pixel précédent et fait la prédiction que le pixel suivant serait le même.
Gardez à l'esprit que si vous avez tous les pixels précédents, vous avez des informations plus pertinentes que tout le pixel précédent. C'est, si vous essayez de prédire la valeur de X, vous devez utiliser les pixels O:
.. OOO ...
..OX
, vous ne voudriez pas aussi d'utiliser le pixel précédent, B, dans le courant de prédire X dans la situation suivante:
OO ... B <- Fin de la ligne
X <- Début de la ligne suivante
vous plutôt faire votre base de prédiction sur les Os.
Comment « sans perte » avez-vous besoin?
Si cela est un vrai scanner il y a une limite à la bande passante / résolution même si elle peut envoyer +/- 64K valeurs, il peut être non physique pour les pixels adjacents d'avoir une différence de plus de dire 8 bits.
Dans ce cas, vous pouvez faire une valeur de pixel de départ pour chaque ligne, puis faire des différences entre chaque pixel.
Cela enduisent les pics, mais il se peut que tous les sommets de plus de « N'bits sont le bruit de toute façon.
Un bon hybride LZ77 / RLE avec des cloches et wwhistles peuvent obtenir merveilleuse compression qui est assez rapide pour décomprimer. Ils seront également plus gros, les compresseurs badder sur des fichiers plus petits en raison de l'absence de frais généraux bibliothèque. Pour une bonne, mais GPLd implentation de cela, consultez PUCrunch