我有一个嵌入式应用程序,其中图像扫描仪发出16位像素流,稍后将这些像素组合成灰度图像。由于我需要在本地保存这些数据并将其转发到网络接口,我想压缩数据流以减少所需的存储空间和网络带宽。
是否有一种简单的算法可用于无损压缩像素数据?
我首先考虑计算两个连续像素之间的差异,然后用霍夫曼代码对这个差异进行编码。不幸的是,像素是无符号的16位量,因此差值可以是-65535 ... +65535范围内的任何位置,这可能导致潜在的巨大码字长度。如果连续出现一些非常长的代码字,我将遇到缓冲区溢出问题。
更新:我的平台是FPGA
答案 0 :(得分:8)
PNG使用标准工具以标准格式提供免费,开源,无损图像压缩。 PNG使用zlib
作为其压缩的一部分。还有一个libpng
。除非您的平台非常不寻常,否则将此代码移植到它上面并不困难。
答案 1 :(得分:3)
您的嵌入式平台上有多少资源?
你能移植zlib并进行gzip压缩吗?即使资源有限,您也应该可以移植LZ77 or LZ88。
答案 2 :(得分:3)
有各种各样的图像压缩库可用。例如,this page只列出了PNG图像的库/工具包。哪种格式/库最适合您将很可能取决于您正在使用的特定资源限制(特别是,您的嵌入式系统是否可以执行浮点运算)。
答案 3 :(得分:2)
无损压缩的目标是能够根据之前的像素预测下一个像素,然后对预测与像素的实际值之间的差异进行编码。这是你最初的想法,但你只是使用前一个像素,并预测下一个像素将是相同的。
请注意,如果您拥有所有之前的像素,则您拥有的信息比前一个像素更多。也就是说,如果您尝试预测X的值,则应使用O像素:
.. OOO ...
..OX
此外,在以下情况下,您不希望在流中使用前一个像素B来预测X:
OO ... B< - 行尾 X< - 下一行的开始
相反,你会根据Os做出预测。
答案 4 :(得分:1)
你需要“无损”吗? 如果这是一个真正的扫描仪,那么带宽/分辨率是有限的,所以即使它可以发送+/- 64K值,相邻像素的差异也可能超过8比特。
在这种情况下,您可以为每一行执行起始像素值,然后在每个像素之间进行差异。
这会抹去峰值,但可能是任何超过'N'的峰都是噪音。
答案 5 :(得分:1)
一个好的LZ77 / RLE混合动力车,可以获得很好的压缩,可以很快地解压缩。由于缺少库开销,它们对较小的文件也将是更大,更糟糕的压缩器。要获得良好但GPLd的实现,请查看PUCrunch