【问题标题】:Automatically choose optimal JPEG compression in OpenCV?在 OpenCV 中自动选择最佳 JPEG 压缩?
【发布时间】:2014-09-28 07:52:53
【问题描述】:

不知道有没有办法在 OpenCV 中自动选择合理的 JPEG 压缩级别?

我获得的当前 JPEG 尺寸太大,将其固定为固定值感觉很脏。如果我记得 Dreamweaver 等图像编辑器中存在此类功能。如果没有这样的功能,我也想知道是否有人知道一种能够在不执行硬盘 IO 的情况下估计这个参数的算法。

std::vector<int> params;
params.push_back(CV_IMWRITE_JPEG_QUALITY);
params.push_back(magic);  //Want a way to estimate magic
cv::imwrite("my.jpg",image,params);

【问题讨论】:

标签: opencv


【解决方案1】:

不幸的是,要“优化”JPEG 压缩,必须学习和应用有关 JPEG 压缩的许多技术细节。因此,许多库不提供全套调整参数。 0-100 JPEG 质量参数已经是一个很好的折衷方案。


ImageMagick 可能有这样的功能。


您正在寻找一种“在 OpenCV 中自动选择合理的 JPEG 压缩级别”的方法。

但是,“合理”是主观的,取决于图片所有者对给定图片中哪些特征很重要的看法。这意味着对于(不同所有者)x(不同图像)的每种组合,感知可能会有所不同。

  • 简短的回答
    • 不,OpenCV 目前不提供此功能。
  • “系统管理员”答案
  • 快速而肮脏的答案
    • 使用二分法(0、100、50、75、87...)来搜索接近指定输出文件大小的 JPEG 质量级别。
    • Secant method 也可能适用。
      • 已编辑:Newton's method 可能没有用,因为没有分析模型就无法获得质量文件大小曲线的一阶导数。
    • 显然这对于​​日常实际使用来说效率太低,因此图书馆不提供。
    • 如果您想使用它,您必须使用自己选择的技术自己实现它。
    • 为避免磁盘 I/O,use cv::imencode which writes to memory instead of to disk
  • 略长的答案
    • 虽然它没有实现此功能,但显然它是一个不错的功能。
    • 如果有人愿意以适合在 OpenCV 中使用的代码质量来实现它,OpenCV 可以考虑接受它。
  • 更长的答案
    • OpenCV 使用jpeglib 或可选的libjpeg-turbo,这两个库都允许配置JPEG 压缩的技术细节。
    • 下面我将重点介绍这些技术细节。

首先阅读:JPEG compression 维基百科


JPEG压缩流水线中,jpeglib或libjpeg-turbo的用户​​可以配置三个压缩步骤:

  • 色度二次采样
    • 在从 RGB 转换为 YCbCr 之后,色度(承载颜色)通道:色度蓝色和色度红色,可选择以相对于亮度 (Y) 通道(也称为强度或灰度通道,后者始终以全分辨率存储。
    • 大多数 JPEG 解码器可以支持这些下采样因子:
      • (1, 1) - 无二次抽样
      • (1, 2), (2, 1), (2, 2) - 适度的二次抽样,其中一个或两个维度可以被二次抽样 2。
      • (1, 4), (2, 4), (4, 2), (4, 1) - 重采样。请注意,原始 JPEG 规范禁止其中一些组合,但大多数 JPEG 解码器仍然能够解码它们。
  • 量化表
    • 每个 JPEG 图像都可以为 DCT 变换系数的“AC 系数”定义一个量化表
    • 每个 JPEG 图像都可以为从 DCT 变换计算的“DC 系数”(即 8x8 块的平均值)定义一个量化表。
    • 量化是 JPEG 压缩的“有损步骤”。因此,技术用户必须决定可以接受多少损失(量化),然后相应地配置量化表。
  • 霍夫曼表
    • Huffman coding 是一种无损压缩技术。换句话说,如果真的可以花时间根据整幅图像的量化 DCT 系数的统计数据优化霍夫曼编码表,,通常可以构造出一个好的霍夫曼编码表。表以优化压缩无需牺牲质量
    • 很遗憾,现实情况更加复杂,而且这种优化通常无法启用。
      • 对于整个图像,它需要将所有 DCT 系数保存在内存中。这会增加内存使用量。
      • 在所有内容都在内存中之前,无法开始写入文件。相比之下,如果库预先选择量化表和霍夫曼表,而不查看 DCT 系数的统计数据,那么库将能够 >在处理像素的行和行时增量写入文件。因为 libjpeg 旨在用于最小分母的设备(包括智能手表,也许还有你的冰箱?),所以能够以最少的内存运行是一项重要功能。

【讨论】:

  • 嗯,我将花一些时间研究这些工具。我认为 JPEG 文件大小曲线是单调递减的,可以用指数建模。因此,在几个点对其进行采样可能比使用迭代更好。另外,可能不是牛顿法,因为它需要二阶导数,比如黄金分割搜索。
  • 谢谢,我什至不知道它是否可以被任何东西建模。这就是我引用正割方法的原因,因为至少需要两个或更多“编码轮”才能了解曲线的样子。一旦您有两个以上的文件大小测量值,似乎二次或多项式拟合可能会很有用。说到昂贵的文件 I/O,遗憾的是 OpenCV 没有 compress-to-memory 功能,但 jpeglib 和 libjpeg-turbo 有。
  • 我错了。 cv::imencode in HighGUI module 是 OpenCV 中的 compress-to-memory 方法。
【解决方案2】:

抱歉,在您压缩文件之前无法确定大小。如果您不着急,请使用不同的质量值压缩图像,然后选择最佳的。

【讨论】:

  • 这是一个相当大胆的说法,但我不介意使用这种策略,但实际上还不清楚如何避免昂贵的文件 IO...
猜你喜欢
  • 1970-01-01
  • 2010-10-22
  • 2017-04-07
  • 2015-06-20
  • 2011-08-09
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多