【问题标题】:Transform image from BGR to sRGB in Numpy/OpenCV在 Numpy/OpenCV 中将图像从 BGR 转换为 sRGB
【发布时间】:2021-04-21 15:11:38
【问题描述】:

给定一个 BGR 格式的 numpy 尺寸数组(宽度、高度、3),我如何将此图像转换为 sRGB 空间? OpenCV (cv2) 没有实现这种转换,也没有实现任何对 sRGB 的转换。

我进行了一些研究,但找不到任何可以执行此操作的函数,甚至找不到我可以遵循的公式来实现我自己的函数。

有什么建议或指导吗?为什么这种转变在互联网上如此晦涩难懂?

【问题讨论】:

  • 我怀疑 BGR 格式已经是 sRGB,通道颠倒了。 OpenCV 将输入的 sRGB 图像读取为 BGR 格式,但不对通道进行线性化。数据按原样读取,但通道被交换。当它写出图像时,它又是 sRGB 格式。但是,如果输入是线性 RGB,那么我怀疑它不会改变它,您必须转换为非线性 sRGB。这可以通过配置文件来完成。
  • @fmw42 如果像素值是线性的,您就会知道,因为它们将大于每个通道 8 位。而且线性和sRGB之间的转换很容易找到,从维基百科开始。
  • 线性并不意味着你有超过 8 位。线性 RGB 只会比 sRGB 更暗
  • @fmw42 你是对的,线性并不自动意味着超过 8 位。但实际上,8位或更少的线性图像不会很有用,质量会太差。所以你不太可能遇到一个。
  • 线性 RGB 通常用于某些类型的处理,例如调整大小以避免某些类型的细微伪影。但是从 sRGB 开始,转换为线性 RGB,进行处理,然后再转换回 sRGB。这不是质量差。它只是更暗。

标签: python numpy opencv


【解决方案1】:

BGR 格式已经是 sRGB,通道颠倒了。 OpenCV 将输入的 sRGB 图像读取为 BGR 格式,但不对通道进行线性化。数据按原样读取,但通道被交换。当它写出图像时,它又是 sRGB 格式。但是,如果输入图像是线性 RGB,那么我怀疑 OpenCV 不会改变它,如果你想要它作为输出,你必须转换为非线性 sRGB。据我所知,OpenCV 没有在任一方向上在非线性和线性 RGB 之间切换的方法。您可以使用 PIL 中的配置文件来做到这一点。

线性 RGB 通常用于某些类型的处理,例如调整大小以避免某些类型的细微伪影。但是从 sRGB 开始,转换为线性 RGB,处理图像,然后再转换回 sRGB。线性并不意味着或质量差。它只是更暗。

这是一个非线性 sRGB 图像,看起来和预期的一样:

这是一个线性 RGB 图像,只是更暗:

线性的来自 Imagemagick 的命令:

convert lena.png -colorspace RGB lena_srgb.png

非线性的是:

convert lena.png -colorspace sRGB lena_srgb.png

它不会改变图像,因为它已经是 sRGB。

大多数工具不区分 RGB 和 sRGB。他们通常将 sRGB 称为 RGB。

【讨论】:

  • 线性 RGB 在我的浏览器上看起来并没有变暗。您确定 imgur 没有对其进行额外的转换吗? Imagemagick 也可能在线性 RGB 上使用浮点数,而不是 8 位整数。
  • IMGUR 不能识别线性 RGB 并将其视为 sRGB。 Imagemagick 始终计算为双精度数,但保存到安装定义的量程范围内。就我而言,安装是 16 位的。我没有告诉它将位深度降低到 8 位。所以这两个图像在位深度上是等效的。尝试其他查看器,例如您的浏览器。
  • 你或 IMGUR 一定在做一些奇怪的事情。如果我使用 Imagemagick 比较来获得 rmse 差异,它会显示:1compare -metric rmse lena_rgb.png lena_srgb.png null: 15372.7 (0.234573)`,这是一个非常大的差异。
  • 谢谢@fmw42!在我看来,我的问题是由于对概念的误解。现在它更有意义了! :)
猜你喜欢
  • 1970-01-01
  • 2017-07-01
  • 2012-11-17
  • 2021-11-24
  • 1970-01-01
  • 2013-06-13
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多