【问题标题】:jpeg lossless transformations - memory consumption?jpeg无损转换 - 内存消耗?
【发布时间】:2012-12-06 22:59:32
【问题描述】:

我刚刚从http://jpegclub.org/jpegtran/ 下载了最新的win32 jpegtran.exe 并观察到以下情况:

我准备了一个 14500 x 10000 像素的 24 BPP jpeg 测试图像。

  • 文件系统中的压缩大小约为 7.5 MB
  • 解压到内存(使用一些图像查看器)会膨胀到大约 450 MB

在无损旋转 (180) 期间监控 jpegtran.exe 命令行工具的内存消耗,我可以看到进程消耗高达 900 MB 内存!

我会假设这种 jpeg 无损转换 不需要将图像文件解码到内存中,而只需对编码文件本身执行一些数学转换 - 保持内存占用非常低。

那么下列哪项是正确的?

  • 此特定工具的实现中存在一些错误
  • 我错过了一些配置开关
  • 我的一些误解(即 jpeg 无损转换也需要将图像解码到内存中?)
  • “数学运算”比“将图像解码到内存”消耗更多的内存

编辑:

根据 JasonD 的回答,原因似乎是后者。所以我会扩展我的问题:

是否有任何实现可以在小块中执行这些操作(以避免高内存使用)?还是总是需要整体完成而没有办法解决?

PS:
我不打算实现我自己的编解码器/算法。相反,我问是否有任何满足我的要求的实现。或者至少理论上可以。

【问题讨论】:

  • 尝试在小块中这样做的问题是输出块需要根据输入重新排序,并且块是可变长度的(因为压缩) - 所以你不能轻易地随机访问它们中的任何一个。也许,您可以对输入文件进行初始传递,而无需实际扩展它,以确定输入流中每个块的开始位置,然后按输出顺序进行处理。不知道是否有人编写过诸如解决方案之类的代码。

标签: memory jpeg codec imaging libjpeg-turbo


【解决方案1】:

我不知道有问题的库,但为了对 jpeg 图像执行无损旋转,您至少必须解压缩 DCT 系数才能旋转它们,然后重新压缩。

完全展开后的 DCT 系数将与原始图像数据大小相同或更大,因为它们具有更多的信息位。

它是无损的,因为 jpeg 中的损失是由 DCT 系数的量化引起的。只要你不解码/重新编码/重新量化这些,就不会产生任何损失。

但这会占用大量内存。

jpeg 压缩的工作原理大致如下:

  • 将图像转换为 YCbCr 色彩空间。
  • 可选择对某些通道进行下采样(颜色误差比亮度误差更不易察觉,因此通常对色度通道进行 2 倍下采样)。这显然是有损的,但非常可预测/稳定。
  • 通过离散余弦变换 (DCT) 变换图像的 8x8 块,将图像移动到频率空间中。 DCT 系数也在 8x8 块中,并且比 8 位图像数据使用更多位进行存储。
  • 按可变数量量化 DCT 系数(这是大多数软件包中的质量设置)。目的是产生尽可能多的小系数,尤其是零系数。这是 jpeg 压缩的主要“有损”方面。
  • 锯齿形穿过 2D 数据,将其转换为大致按频率顺序排列的 1D 系数流。高频更有可能被归零,因此理想情况下,许多数据包将以可以截断的零流结束。
  • 使用霍夫曼编码压缩(无损)(现在可压缩的)数据。

因此,“无损”转换会希望尽可能避免这样做 - 尤其是 DCT 量化之外的任何事情,但这并不能避免扩展数据。

【讨论】:

  • DCT 系数将大于最终(或原始)解压缩图像。
  • +1,我建议 OP 看看 David Salomon's Bible 的压缩方法。
  • 顺便说一句:libjpeg.txt 中的 Memory usage 部分提供了有关内存要求的更多详细信息。对于 DCT 系数:“这需要 2 个字节/系数。在典型的 2x2 采样中,彩色图像每像素 3 个字节。最坏情况(1x1 采样)需要 6 个字节/像素。对于灰度,图 2 字节/像素.".
  • 是的,我忽略了下采样方面,我可能应该提到这一点。我已经修改了我的答案以明确这一点。好地方。
猜你喜欢
  • 2012-09-11
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-22
  • 2011-10-03
  • 2012-11-24
相关资源
最近更新 更多