将XYZ映射到线性RGB的正确矩阵是什么,以适用于sRGB?

6

看起来有三个主要的映射矩阵变体,它们从第三或第四位小数开始分歧。哪一个应被视为标准矩阵?

  1. Bruce Lindbloom的http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
    根据红、绿、蓝和D65参考白点(X、Y、Z)的(x,y)计算。
  RGB -> XYZ
  +0.4124564 +0.3575761 +0.1804375  
  +0.2126729 +0.7151522 +0.0721750  
  +0.0193339 +0.1191920 +0.9503041  
  XYZ -> RGB (by inverting RGB -> XYZ)
  +3.2404542 -1.5371385 -0.4985314  
  -0.9692660 +1.8760108 +0.0415560  
  +0.0556434 -0.2040259 +1.0572252  
  1. W3C https://www.w3.org/Graphics/Color/srgb
    EasyRGB https://easyrgb.com/en/math.php 似乎使用了 W3C,但被截断了。
  XYZ -> RGB
  +3.2406255 -1.5372080 -0.4986286  
  -0.9689307 +1.8757561 +0.0415175  
  +0.0557101 -0.2040211 +1.0569959  
是指定了sRGB颜色空间的标准。维基百科 https://en.wikipedia.org/wiki/SRGB#Specification_of_the_transformation 声称为sRGB规范。
  XYZ -> RGB
  +3.24096994 -1.53738318 -0.49861076  
  -0.96924364 +1.87596750 +0.04155506  
  +0.05563008 -0.20397696 +1.05697151  
4个回答

5

严格来说,这些都不正确,因为它们是从IEC 61966-2-1:1999给出的原色和白点中推导出来的,并在某些任意小数位处四舍五入。这里有两个真正的选择,要么使用标准所给出的矩阵,即四舍五入到4个小数位,要么直接以完整的机器精度(理想情况下是双精度)计算归一化的主要矩阵及其逆。

IEC 61966-2-1:1999

MATRIX_sRGB_TO_XYZ = np.array([
    [0.4124, 0.3576, 0.1805],
    [0.2126, 0.7152, 0.0722],
    [0.0193, 0.1192, 0.9505],
])
"""
*sRGB* colourspace to *CIE XYZ* tristimulus values matrix.

MATRIX_sRGB_TO_XYZ : array_like, (3, 3)
"""

MATRIX_XYZ_TO_sRGB = np.array([
    [3.2406, -1.5372, -0.4986],
    [-0.9689, 1.8758, 0.0415],
    [0.0557, -0.2040, 1.0570],
])
"""
*CIE XYZ* tristimulus values to *sRGB* colourspace matrix.

MATRIX_XYZ_TO_sRGB : array_like, (3, 3)
"""

ITU-R BT.709是IEC 61966-2-1:1999所使用的原色和白点,但并未指定矩阵。例如,以双精度计算它们:
>>> import colour
>>> import numpy as np
>>> np.set_printoptions(formatter={'float': '{:0.15f}'.format}, suppress=True)
>>> colour.models.RGB_COLOURSPACE_BT709.matrix_RGB_to_XYZ
array([[0.412390799265959, 0.357584339383878, 0.180480788401834],
       [0.212639005871510, 0.715168678767756, 0.072192315360734],
       [0.019330818715592, 0.119194779794626, 0.950532152249661]])
>>> colour.models.RGB_COLOURSPACE_BT709.matrix_XYZ_to_RGB
array([[3.240969941904523, -1.537383177570094, -0.498610760293003],
       [-0.969243636280880, 1.875967501507721, 0.041555057407176],
       [0.055630079696994, -0.203976958888977, 1.056971514242879]])

从技术上讲,舍入差异应该被使用8位整数表示的量化效应所吸收,但是当您使用浮点值并且IEC 61966-2-1:1999矩阵无法正确往返时,它们会产生后果。
问题在于提供RGB到/from CIE XYZ的两个基色/白点和转换矩阵会产生歧义。你选择哪一个?人们倾向于选择矩阵,因为它们已经计算出来了,这可以通过运行基本的Google Search进行验证。
为了与其他软件进行交换,您可能需要选择已发布的矩阵,但是对于内部颜色转换工作,推荐使用派生矩阵,因为如果您执行大量前后转换,则会减少舍入误差。但实际上,您会发现这并不太重要。

重要的条件是矩阵的第二行总和为1(在RGB到XYZ矩阵中),这就是BT.709 YCbCr系数的来源以及BT.709矩阵的构建方式。所有这些都在SMPTE RP 177中讨论过。此外,XYZ到RGB矩阵在NIF RGB规范中以更准确的形式指定(尽管不是正确的形式),这是sRGB的初始版本。http://www.graphcomp.com/info/specs/livepicture/fpx.pdf第55页有详细说明。 - Валерий Заподовников

3

CSS Color 4的早期版本使用了Lindbloom网站的矩阵。我修改了示例代码,直接使用计算出的矩阵,从而消除了一些令人困扰的回路错误。

如果我按照Lindbloom网站上给出的计算这些值的方法来计算(也给出了这个方法),我得不到他在sRGB方面的答案。我怀疑他的计算中出现了错误,也许是错误的白点值?


嗨,克里斯,我相信布鲁斯正在/曾经使用ASTM E308-01的白点,其值为:0.3127266150和0.3290231300。相关:Elle Stone在https://ninedegreesbelow.com/photography/well-behaved-profiles-quest.html#white-point-values上有一篇关于各种“标准”中不同白点的文章。 - Myndex

2

W3C的定义链接是最早的、非标准化的提议。它已被弃用,因为由于过度舍入而存在错误。IEC 61966-2-1:1999最终纠正了这个错误,并在IEC 61966-2-1:1999/AMD1:2003中进一步修订。

CSS Color 4中有一个W3C的定义,它参考了IEC标准中的主要色度和白点 https://drafts.csswg.org/css-color-4/#valdef-color-srgb 该规范附带的(信息性的)示例代码使用双精度计算出的这些色度矩阵,并且没有任何舍入。 https://drafts.csswg.org/css-color-4/#color-conversion-code

如果四舍五入到小数点后8位,它们与维基百科文章中给出的矩阵完全相同。


非常好的资源,谢谢。这是我见过的最高精度。 - boot-and-bonnet

1
所以维基百科有一个错误,在IEC标准中使用四位小数的XYZ矩阵(因为反转矩阵第二行必须是BT.709-2矩阵系数,请参见SMPTE 177)。它是在这里介绍的:https://en.wikipedia.org/w/index.php?title=SRGB&diff=949593434&oldid=946057212 我撤销了那个更改,现在两个矩阵都是IEC的。此外,我从sRGB IEC标准的第一次修正中添加了更高精度的XYZ到BT.709矩阵(是的,我有它)。他们说这已经足够16位了。他们还将四位小数矩阵恢复为XYZ,但没有进一步定义。https://en.wikipedia.org/w/index.php?title=SRGB&diff=1018331095&oldid=1018328711 此外,当然,@kel-solaar 在这里是正确的,您可以进一步定义这两个矩阵,但他没有澄清的是,反演应该更高精度,因为这就是矩阵反演的工作方式。(不是 YCbCr,那只是 YCbCr 矩阵的工作方式(反演后有 2 个零和 3 个一),但这适用于 XYZ 和 ICtCp,ITU 建议使用具有 14 位小数点的 ICtCp 矩阵。) 此外,我认为您不需要真正增加精度,只需增加反转矩阵的精度即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接