操作 CIE xyY 或 XYZ 颜色时如何处理负值?

发布于 2025-01-15 05:03:07 字数 1292 浏览 3 评论 0原文

我正在编写一些图像处理代码来进行一些创造性的色域限制,我想将其用于颜色分级应用程序。我正在构建在 达芬奇广色域色彩空间中运行,通常使用达芬奇中间对数编码< /a>,因为这是我在颜色管理工作流程中的典型工作空间。为此,我想将输入转换为 xyY,限制 xy 的值以适合我所需的色域,然后转换回达芬奇宽色域/中级。

以下是我要执行的步骤:

  1. 将 DaVinci Intermediate RGB 转换为线性 RGB
  2. 乘以 DWG 到 XYZ 转换矩阵。
  3. 将 XYZ 转换为 xyY。
  4. 修改 x 和 y 以使其落入色域内。
  5. 将 xyY 转换为 XYZ。
  6. 乘以 XYZ 到 DWG 转换矩阵。
  7. 将线性 RGB 转换为 DaVinci Intermediate。

这对于大多数情况都适用,我还验证了不修改 x 和 y 的往返可以按预期工作。对于极度饱和的蓝色会出现这个问题。以达芬奇广色域/中间色中的以下 RGB 值为例:[0, 0, 1.0] 让我们继续进行:

  1. 转换为线性:[0, 0, 100]
  2. 转换为 XYZ:[10.11,-14.78, 132.59]
  3. 转换为 xyY:[0.08 ,-0.12,-14.78]
  4. 修改 x 和 y 以适应我的色域:[0.18, 0.07, -14.78]
  5. 转换回 XYZ:[-35.64,-14.78,-149.08]
  6. 转换回 DWG 线性:[-27.99,-27.99,-117.44]
  7. 转换回 DaVinci Intermediate:[-292.34, -292.34, -1226.52]

如您所见,结果是无意义的,但仅限于这些极端的蓝色值。对我来说,很明显这是由达芬奇广色域中的蓝色原色引起的,它具有负 y 坐标 ([0.0790, -0.1155])。这会导致负亮度 (Y = -14.78),并且当弄乱 xy 值而不同时处理亮度时,事情就会变得混乱。

以这种方式进行色域限制时,如何处理 xyY 和 XYZ 中的负值?

I'm writing some image processing code to do some creative color gamut limiting that I want to use for color grading applicationgs. I'm building to operate in the Davinci Wide Gamut color space, typically using the DaVinci Intermediate logarithmic encoding, since that is my typical working space in a color managed workflow. To do this, I want to convert the input to xyY, limit the value of xy to fit within my desired gamut and then convert back to DaVinci Wide Gamut/Intermediate.

These are the steps I'm following:

  1. Convert DaVinci Intermediate RGB to linear RGB
  2. Multiply by DWG to XYZ conversion matrix.
  3. Convert XYZ to xyY.
  4. Modify x and y to fall within gamut.
  5. Convert xyY to XYZ.
  6. Multiply by XYZ to DWG conversion matrix.
  7. Convert linear RGB to DaVinci Intermediate.

This works fine for most cases, I have also verified that roundtripping without modification of x and y works as intended. The problem occurs for for extremely saturated blues. Take the following RGB values in Davinci Wide Gamut/Intermediate as an example: [0, 0, 1.0]
Let's follow along:

  1. Convert to linear: [0, 0, 100]
  2. Convert to XYZ: [10.11,-14.78, 132.59]
  3. Convert to xyY: [0.08,-0.12,-14.78]
  4. Modifying x and y to fit in my gamut: [0.18, 0.07, -14.78]
  5. Convert back to XYZ: [-35.64,-14.78,-149.08]
  6. Convert back to DWG linear: [-27.99,-27.99,-117.44]
  7. Convert back to DaVinci Intermediate: [-292.34, -292.34, -1226.52]

As you can see, the result is nonsensical, but only for these extreme blue values. To me, it seems pretty clear that this is caused by the blue primary in DaVinci Wide Gamut which has a negative y coordinate ([0.0790, -0.1155]). This causes negative luminance (Y = -14.78) and when messing with the xy values without dealing with the luminance at the same time, things go haywire.

How do I deal with negative values in xyY and XYZ when doing gamut limiting in this way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

廻憶裏菂餘溫 2025-01-22 05:03:07

步骤 2 XYZ < 0 ?? Afaik CIELAB XYZ 应始终 >= 0。
您的任何其他 XYZ 是否 < 0 ?
RGB有相当多的<->例如,网络上的 XYZ 公式和代码片段

# https://python-colormath.readthedocs.io/en/latest/conversions.html

from colormath.color_objects import sRGBColor, LabColor, XYZColor
from colormath.color_conversions import convert_color

print( 80 * "▄" )

c = [ 0., 0., 1. ]
rgb = sRGBColor( *c )
lab = convert_color( rgb, LabColor )  # .lab_l .lab_a .lab_b
xyz = convert_color( rgb, XYZColor )  # .xyz_x .xyz_y .xyz_z
print( "rgb:", c )
print( lab )
print( xyz )

# rgb: [0.0, 0.0, 1.0]
# LabColor (lab_l:32.2994 lab_a:79.1914 lab_b:-107.8655)
# XYZColor (xyz_x:0.1805 xyz_y:0.0722 xyz_z:0.9504)  # 0 - 1, not XYZ100

Step 2 XYZ < 0 ?? Afaik CIELAB XYZ should always be >= 0.
Are any other of your XYZ s < 0 ?
There are quite a few RGB <-> XYZ formulas and code snippets on the web, for example

# https://python-colormath.readthedocs.io/en/latest/conversions.html

from colormath.color_objects import sRGBColor, LabColor, XYZColor
from colormath.color_conversions import convert_color

print( 80 * "▄" )

c = [ 0., 0., 1. ]
rgb = sRGBColor( *c )
lab = convert_color( rgb, LabColor )  # .lab_l .lab_a .lab_b
xyz = convert_color( rgb, XYZColor )  # .xyz_x .xyz_y .xyz_z
print( "rgb:", c )
print( lab )
print( xyz )

# rgb: [0.0, 0.0, 1.0]
# LabColor (lab_l:32.2994 lab_a:79.1914 lab_b:-107.8655)
# XYZColor (xyz_x:0.1805 xyz_y:0.0722 xyz_z:0.9504)  # 0 - 1, not XYZ100
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文